From c19fb2ab58d0ea77263a5eafa28fe2cf6ca9dec6 Mon Sep 17 00:00:00 2001 From: lin <429426691@qq.com> Date: Fri, 15 Sep 2017 18:10:51 +0800 Subject: [PATCH 1/5] Add bsp apollo2 --- bsp/apollo2/SConscript | 14 + bsp/apollo2/SConstruct | 34 + bsp/apollo2/applications/SConscript | 11 + bsp/apollo2/applications/application.c | 95 + bsp/apollo2/applications/startup.c | 93 + bsp/apollo2/board/Sconscript | 14 + bsp/apollo2/board/board.c | 146 + bsp/apollo2/board/board.h | 17 + bsp/apollo2/board/hw_led.c | 302 + bsp/apollo2/board/hw_led.h | 60 + bsp/apollo2/board/hw_uart.c | 413 ++ bsp/apollo2/board/hw_uart.h | 23 + bsp/apollo2/libraries/SConscript | 14 + bsp/apollo2/libraries/drivers/SConscript | 29 + bsp/apollo2/libraries/drivers/am_mcu_apollo.h | 132 + .../libraries/drivers/hal/am_hal_adc.c | 553 ++ .../libraries/drivers/hal/am_hal_adc.h | 348 ++ .../libraries/drivers/hal/am_hal_cachectrl.c | 576 ++ .../libraries/drivers/hal/am_hal_cachectrl.h | 211 + .../libraries/drivers/hal/am_hal_clkgen.c | 491 ++ .../libraries/drivers/hal/am_hal_clkgen.h | 206 + .../libraries/drivers/hal/am_hal_ctimer.c | 1687 ++++++ .../libraries/drivers/hal/am_hal_ctimer.h | 278 + .../libraries/drivers/hal/am_hal_debug.c | 81 + .../libraries/drivers/hal/am_hal_debug.h | 89 + .../libraries/drivers/hal/am_hal_flash.c | 1449 +++++ .../libraries/drivers/hal/am_hal_flash.h | 297 + .../libraries/drivers/hal/am_hal_global.c | 59 + .../libraries/drivers/hal/am_hal_global.h | 114 + .../libraries/drivers/hal/am_hal_gpio.c | 503 ++ .../libraries/drivers/hal/am_hal_gpio.h | 684 +++ .../drivers/hal/am_hal_i2c_bit_bang.c | 757 +++ .../drivers/hal/am_hal_i2c_bit_bang.h | 100 + .../libraries/drivers/hal/am_hal_interrupt.c | 407 ++ .../libraries/drivers/hal/am_hal_interrupt.h | 159 + .../libraries/drivers/hal/am_hal_iom.c | 4426 ++++++++++++++ .../libraries/drivers/hal/am_hal_iom.h | 559 ++ .../libraries/drivers/hal/am_hal_ios.c | 1303 ++++ .../libraries/drivers/hal/am_hal_ios.h | 362 ++ .../libraries/drivers/hal/am_hal_itm.c | 453 ++ .../libraries/drivers/hal/am_hal_itm.h | 107 + .../libraries/drivers/hal/am_hal_mcuctrl.c | 292 + .../libraries/drivers/hal/am_hal_mcuctrl.h | 212 + .../libraries/drivers/hal/am_hal_otp.c | 173 + .../libraries/drivers/hal/am_hal_otp.h | 108 + .../libraries/drivers/hal/am_hal_pdm.c | 158 + .../libraries/drivers/hal/am_hal_pdm.h | 665 +++ .../libraries/drivers/hal/am_hal_pin.h | 557 ++ .../libraries/drivers/hal/am_hal_pwrctrl.c | 558 ++ .../libraries/drivers/hal/am_hal_pwrctrl.h | 342 ++ .../libraries/drivers/hal/am_hal_queue.c | 286 + .../libraries/drivers/hal/am_hal_queue.h | 123 + .../libraries/drivers/hal/am_hal_reset.c | 160 + .../libraries/drivers/hal/am_hal_reset.h | 119 + .../libraries/drivers/hal/am_hal_rtc.c | 678 +++ .../libraries/drivers/hal/am_hal_rtc.h | 185 + .../libraries/drivers/hal/am_hal_stimer.c | 525 ++ .../libraries/drivers/hal/am_hal_stimer.h | 242 + .../libraries/drivers/hal/am_hal_sysctrl.c | 851 +++ .../libraries/drivers/hal/am_hal_sysctrl.h | 119 + .../libraries/drivers/hal/am_hal_systick.c | 453 ++ .../libraries/drivers/hal/am_hal_systick.h | 83 + .../libraries/drivers/hal/am_hal_tpiu.c | 381 ++ .../libraries/drivers/hal/am_hal_tpiu.h | 193 + .../libraries/drivers/hal/am_hal_ttp.c | 205 + .../libraries/drivers/hal/am_hal_ttp.h | 72 + .../libraries/drivers/hal/am_hal_uart.c | 1160 ++++ .../libraries/drivers/hal/am_hal_uart.h | 345 ++ .../libraries/drivers/hal/am_hal_vcomp.c | 287 + .../libraries/drivers/hal/am_hal_vcomp.h | 176 + .../libraries/drivers/hal/am_hal_wdt.c | 454 ++ .../libraries/drivers/hal/am_hal_wdt.h | 184 + .../libraries/drivers/regs/am_reg_adc.h | 864 +++ .../drivers/regs/am_reg_base_addresses.h | 77 + .../libraries/drivers/regs/am_reg_cachectrl.h | 415 ++ .../libraries/drivers/regs/am_reg_clkgen.h | 501 ++ .../libraries/drivers/regs/am_reg_ctimer.h | 1915 ++++++ .../libraries/drivers/regs/am_reg_flashctrl.h | 68 + .../libraries/drivers/regs/am_reg_gpio.h | 5218 +++++++++++++++++ .../libraries/drivers/regs/am_reg_iomstr.h | 587 ++ .../libraries/drivers/regs/am_reg_ioslave.h | 514 ++ .../libraries/drivers/regs/am_reg_itm.h | 657 +++ .../libraries/drivers/regs/am_reg_jedec.h | 215 + .../libraries/drivers/regs/am_reg_macros.h | 312 + .../drivers/regs/am_reg_macros_asm.h | 162 + .../libraries/drivers/regs/am_reg_mcuctrl.h | 607 ++ .../libraries/drivers/regs/am_reg_nvic.h | 325 + .../libraries/drivers/regs/am_reg_pdm.h | 374 ++ .../libraries/drivers/regs/am_reg_pwrctrl.h | 485 ++ .../libraries/drivers/regs/am_reg_rstgen.h | 211 + .../libraries/drivers/regs/am_reg_rtc.h | 326 + .../libraries/drivers/regs/am_reg_sysctrl.h | 653 +++ .../libraries/drivers/regs/am_reg_systick.h | 137 + .../libraries/drivers/regs/am_reg_tpiu.h | 164 + .../libraries/drivers/regs/am_reg_uart.h | 612 ++ .../libraries/drivers/regs/am_reg_vcomp.h | 200 + .../libraries/drivers/regs/am_reg_wdt.h | 189 + bsp/apollo2/libraries/startup/SConscript | 26 + .../libraries/startup/arm/startup_keil.s | 359 ++ .../libraries/startup/gcc/startup_gcc.c | 316 + .../libraries/startup/iar/startup_iar.c | 312 + bsp/apollo2/project.uvprojx | 740 +++ bsp/apollo2/rtconfig.h | 93 + bsp/apollo2/rtconfig.py | 84 + bsp/apollo2/template.uvoptx | 164 + bsp/apollo2/template.uvprojx | 418 ++ 106 files changed, 46302 insertions(+) create mode 100644 bsp/apollo2/SConscript create mode 100644 bsp/apollo2/SConstruct create mode 100644 bsp/apollo2/applications/SConscript create mode 100644 bsp/apollo2/applications/application.c create mode 100644 bsp/apollo2/applications/startup.c create mode 100644 bsp/apollo2/board/Sconscript create mode 100644 bsp/apollo2/board/board.c create mode 100644 bsp/apollo2/board/board.h create mode 100644 bsp/apollo2/board/hw_led.c create mode 100644 bsp/apollo2/board/hw_led.h create mode 100644 bsp/apollo2/board/hw_uart.c create mode 100644 bsp/apollo2/board/hw_uart.h create mode 100644 bsp/apollo2/libraries/SConscript create mode 100644 bsp/apollo2/libraries/drivers/SConscript create mode 100644 bsp/apollo2/libraries/drivers/am_mcu_apollo.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_adc.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_adc.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_cachectrl.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_cachectrl.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_clkgen.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_clkgen.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_ctimer.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_ctimer.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_debug.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_debug.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_flash.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_flash.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_global.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_global.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_gpio.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_gpio.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_i2c_bit_bang.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_i2c_bit_bang.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_interrupt.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_interrupt.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_iom.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_iom.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_ios.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_ios.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_itm.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_itm.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_mcuctrl.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_mcuctrl.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_otp.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_otp.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_pdm.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_pdm.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_pin.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_pwrctrl.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_pwrctrl.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_queue.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_queue.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_reset.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_reset.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_rtc.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_rtc.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_stimer.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_stimer.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_sysctrl.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_sysctrl.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_systick.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_systick.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_tpiu.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_tpiu.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_ttp.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_ttp.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_uart.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_uart.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_vcomp.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_vcomp.h create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_wdt.c create mode 100644 bsp/apollo2/libraries/drivers/hal/am_hal_wdt.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_adc.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_base_addresses.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_cachectrl.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_clkgen.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_ctimer.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_flashctrl.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_gpio.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_iomstr.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_ioslave.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_itm.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_jedec.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_macros.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_macros_asm.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_mcuctrl.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_nvic.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_pdm.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_pwrctrl.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_rstgen.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_rtc.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_sysctrl.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_systick.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_tpiu.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_uart.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_vcomp.h create mode 100644 bsp/apollo2/libraries/drivers/regs/am_reg_wdt.h create mode 100644 bsp/apollo2/libraries/startup/SConscript create mode 100644 bsp/apollo2/libraries/startup/arm/startup_keil.s create mode 100644 bsp/apollo2/libraries/startup/gcc/startup_gcc.c create mode 100644 bsp/apollo2/libraries/startup/iar/startup_iar.c create mode 100644 bsp/apollo2/project.uvprojx create mode 100644 bsp/apollo2/rtconfig.h create mode 100644 bsp/apollo2/rtconfig.py create mode 100644 bsp/apollo2/template.uvoptx create mode 100644 bsp/apollo2/template.uvprojx diff --git a/bsp/apollo2/SConscript b/bsp/apollo2/SConscript new file mode 100644 index 0000000000..744d8d7821 --- /dev/null +++ b/bsp/apollo2/SConscript @@ -0,0 +1,14 @@ +# for module compiling +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/bsp/apollo2/SConstruct b/bsp/apollo2/SConstruct new file mode 100644 index 0000000000..1f57277560 --- /dev/null +++ b/bsp/apollo2/SConstruct @@ -0,0 +1,34 @@ +import os +import sys +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +from building import * + +TARGET = 'rtthread_apollo2.' + rtconfig.TARGET_EXT + +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) + +if rtconfig.PLATFORM == 'iar': + env.Replace(CCCOM = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES']) + env.Replace(ARFLAGS = ['']) + env.Replace(LINKCOM = ['$LINK $SOURCES $LINKFLAGS -o $TARGET --map project.map']) + +Export('RTT_ROOT') +Export('rtconfig') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/apollo2/applications/SConscript b/bsp/apollo2/applications/SConscript new file mode 100644 index 0000000000..01eb940dfb --- /dev/null +++ b/bsp/apollo2/applications/SConscript @@ -0,0 +1,11 @@ +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +cwd = os.path.join(str(Dir('#')), 'applications') +src = Glob('*.c') +CPPPATH = [cwd, str(Dir('#'))] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/apollo2/applications/application.c b/bsp/apollo2/applications/application.c new file mode 100644 index 0000000000..80f0963202 --- /dev/null +++ b/bsp/apollo2/applications/application.c @@ -0,0 +1,95 @@ +/* + * File : application.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2015, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2017-09-14 Haley the first version + */ + +/** + * @addtogroup APOLLO2 + */ +/*@{*/ + +#include +#include +#ifdef RT_USING_FINSH +#include +#include +#endif + +#include "hw_led.h" + +ALIGN(RT_ALIGN_SIZE) +static rt_uint8_t led_stack[ 512 ]; +static struct rt_thread led_thread; + +static void led_thread_entry(void* parameter) +{ + unsigned int count=0; + + rt_hw_led_init(0); + rt_hw_led_init(1); + + while (1) + { + /* led1 on */ +#ifndef RT_USING_FINSH + rt_kprintf("led on, count : %d\r\n",count); +#endif + count++; + rt_hw_led_on(0); + rt_thread_delay( RT_TICK_PER_SECOND/2 ); /* sleep 0.5 second and switch to other thread */ + + /* led1 off */ +#ifndef RT_USING_FINSH + rt_kprintf("led off\r\n"); +#endif + rt_hw_led_off(0); + rt_thread_delay( RT_TICK_PER_SECOND/2 ); + } +} + +void rt_init_thread_entry(void* parameter) +{ + #ifdef RT_USING_COMPONENTS_INIT + /* initialization RT-Thread Components */ + rt_components_init(); + #endif +} + +int rt_application_init(void) +{ + rt_thread_t init_thread; + + rt_err_t result; + + /* init led thread */ + result = rt_thread_init(&led_thread, + "led", + led_thread_entry, + RT_NULL, + (rt_uint8_t*)&led_stack[0], + sizeof(led_stack), + 7, + 5); + if (result == RT_EOK) + { + rt_thread_startup(&led_thread); + } + + init_thread = rt_thread_create("init", rt_init_thread_entry, RT_NULL, 1024, + RT_THREAD_PRIORITY_MAX / 3, 20); + if (init_thread != RT_NULL) + rt_thread_startup(init_thread); + + return 0; +} + +/*@}*/ diff --git a/bsp/apollo2/applications/startup.c b/bsp/apollo2/applications/startup.c new file mode 100644 index 0000000000..5459c51f46 --- /dev/null +++ b/bsp/apollo2/applications/startup.c @@ -0,0 +1,93 @@ +/* + * File : startup.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2015, RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://openlab.rt-thread.com/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2017-09-11 Haley the first version + */ + +#include +#include + +#include "board.h" + +/** + * @addtogroup Apollo2 + */ + +/*@{*/ + +extern int rt_application_init(void); + +#ifdef __CC_ARM +extern int Image$$RW_IRAM1$$ZI$$Limit; +#define AM_SRAM_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit) +#elif __ICCARM__ +#pragma section="HEAP" +#define AM_SRAM_BEGIN (__segment_end("HEAP")) +#else +extern int __bss_end; +#define NRF_SRAM_BEGIN (&__bss_end) +#endif + +/** + * This function will startup RT-Thread RTOS. + */ +void rtthread_startup(void) +{ + /* init board */ + rt_hw_board_init(); + + /* show version */ + rt_show_version(); + + /* init tick */ + rt_system_tick_init(); + + /* init kernel object */ + rt_system_object_init(); + + /* init timer system */ + rt_system_timer_init(); + +#ifdef RT_USING_HEAP + rt_system_heap_init((void*)AM_SRAM_BEGIN, (void*)AM_SRAM_END); +#endif + + /* init scheduler system */ + rt_system_scheduler_init(); + + /* init application */ + rt_application_init(); + + /* init timer thread */ + rt_system_timer_thread_init(); + + /* init idle thread */ + rt_thread_idle_init(); + + /* start scheduler */ + rt_system_scheduler_start(); + + /* never reach here */ + return ; +} + +int main(void) +{ + /* disable interrupt first */ + // rt_hw_interrupt_disable(); + + /* startup RT-Thread RTOS */ + rtthread_startup(); + + return 0; +} + +/*@}*/ diff --git a/bsp/apollo2/board/Sconscript b/bsp/apollo2/board/Sconscript new file mode 100644 index 0000000000..aa1e87d860 --- /dev/null +++ b/bsp/apollo2/board/Sconscript @@ -0,0 +1,14 @@ +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd] + +#remove other no use files +#SrcRemove(src, '*.c') + +group = DefineGroup('Board', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') \ No newline at end of file diff --git a/bsp/apollo2/board/board.c b/bsp/apollo2/board/board.c new file mode 100644 index 0000000000..8e1c3b8e88 --- /dev/null +++ b/bsp/apollo2/board/board.c @@ -0,0 +1,146 @@ +/* + * File : board.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009 RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2017-09-14 Haley first implementation + */ +#include "board.h" + +#include +#include + +#include "am_mcu_apollo.h" +#include "hal/am_hal_clkgen.h" +#include "hal/am_hal_cachectrl.h" +#include "hw_uart.h" + +#define TICK_RATE_HZ RT_TICK_PER_SECOND +#define SYSTICK_CLOCK_HZ ( 32768UL ) +#define WAKE_INTERVAL ( (uint32_t) ((SYSTICK_CLOCK_HZ / TICK_RATE_HZ)) ) + +/** + * This is the timer interrupt service routine. + * + */ +void am_stimer_cmpr0_isr(void) +{ + /* Check the timer interrupt status */ + am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREA); + am_hal_stimer_compare_delta_set(0, WAKE_INTERVAL); + + if (rt_thread_self() != RT_NULL) + { + /* enter interrupt */ + rt_interrupt_enter(); + + rt_tick_increase(); + + /* leave interrupt */ + rt_interrupt_leave(); + } +} + +/** + * This is the SysTick Configure. + * + */ +void SysTick_Configuration(void) +{ + /* Set the main clk */ + am_hal_clkgen_sysclk_select(AM_HAL_CLKGEN_SYSCLK_MAX); + + /* Enable compare A interrupt in STIMER */ + am_hal_stimer_int_enable(AM_HAL_STIMER_INT_COMPAREA); + + /* Enable the timer interrupt in the NVIC */ + am_hal_interrupt_enable(AM_HAL_INTERRUPT_STIMER_CMPR0); + + /* Configure the STIMER and run */ + am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE); + am_hal_stimer_compare_delta_set(0, WAKE_INTERVAL); + am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ | + AM_HAL_STIMER_CFG_COMPARE_A_ENABLE); +} + +/** + * This is the CacheCtrl Enable. + * + */ +void CacheCtrl_Enable(void) +{ + am_hal_cachectrl_enable(&am_hal_cachectrl_defaults); +} + +/** + * This is the low power operation. + * This function enables several power-saving features of the MCU, and + * disables some of the less-frequently used peripherals. It also sets the + * system clock to 24 MHz. + */ +void am_low_power_init(void) +{ + /* Enable internal buck converters */ + am_hal_pwrctrl_bucks_init(); + + /* Initialize for low power in the power control block */ + am_hal_pwrctrl_low_power_init(); + + /* Turn off the voltage comparator as this is enabled on reset */ + am_hal_vcomp_disable(); + + /* Run the RTC off the LFRC */ + am_hal_rtc_osc_select(AM_HAL_RTC_OSC_LFRC); + + /* Stop the XT and LFRC */ + am_hal_clkgen_osc_stop(AM_HAL_CLKGEN_OSC_XT); + // am_hal_clkgen_osc_stop(AM_HAL_CLKGEN_OSC_LFRC); + + /* Disable the RTC */ + am_hal_rtc_osc_disable(); +} + +/** + * This is the deep power save. + * + */ +void deep_power_save(void) +{ + am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP); +} + +/** + * This function will initial APOLLO2 board. + */ +void rt_hw_board_init(void) +{ + /* Set the clock frequency */ + SysTick_Configuration(); + + /* Set the default cache configuration */ + CacheCtrl_Enable(); + + /* Configure the board for low power operation */ + //am_low_power_init(); + +#ifdef RT_USING_IDLE_HOOK + rt_thread_idle_sethook(deep_power_save); +#endif + +#ifdef RT_USING_CONSOLE + rt_hw_uart_init(); + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif + +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif +} + +/*@}*/ diff --git a/bsp/apollo2/board/board.h b/bsp/apollo2/board/board.h new file mode 100644 index 0000000000..8bafd7dfa2 --- /dev/null +++ b/bsp/apollo2/board/board.h @@ -0,0 +1,17 @@ +#ifndef __BOARD_H_ +#define __BOARD_H_ + +#include + +// Internal SRAM memory size[Kbytes] <8-256> +// Default: 256 +#define AM_SRAM_SIZE 256 +#define AM_SRAM_END (0x10000000 + AM_SRAM_SIZE * 1024) + +/* USART driver select. */ +#define RT_USING_UART0 +#define RT_USING_UART1 + +void rt_hw_board_init(void); + +#endif /* __BOARD_H__ */ diff --git a/bsp/apollo2/board/hw_led.c b/bsp/apollo2/board/hw_led.c new file mode 100644 index 0000000000..71f6c47db5 --- /dev/null +++ b/bsp/apollo2/board/hw_led.c @@ -0,0 +1,302 @@ +/* + * File : hw_led.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2017, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2017-09-14 Haley the first version + */ + +#include +#include "am_mcu_apollo.h" +#include "hw_led.h" + +#define AM_GPIO_LED0 46 +#define AM_GPIO_LED1 47 +#define AM_GPIO_LED2 48 +#define AM_GPIO_LED3 49 + +#define AM_NUM_LEDS 4 + +rt_hw_led_t am_psLEDs[AM_NUM_LEDS] = +{ + {AM_GPIO_LED0, AM_LED_ON_LOW | AM_LED_POL_DIRECT_DRIVE_M}, + {AM_GPIO_LED1, AM_LED_ON_LOW | AM_LED_POL_DIRECT_DRIVE_M}, + {AM_GPIO_LED2, AM_LED_ON_LOW | AM_LED_POL_DIRECT_DRIVE_M}, + {AM_GPIO_LED3, AM_LED_ON_LOW | AM_LED_POL_DIRECT_DRIVE_M}, +}; + +/** + * @brief Configures the necessary pins for an array of LEDs + * + * @param LEDNum is the LED number. + * + * This function configures a GPIO to drive an LED in a low-power way. + * + * @return None. + */ +void rt_hw_led_init(rt_uint32_t LEDNum) +{ + rt_hw_led_t *psLED = am_psLEDs + LEDNum; + + /* Handle Direct Drive Versus 3-State (with pull-up or no buffer) */ + if ( AM_LED_POL_DIRECT_DRIVE_M & psLED->Polarity ) + { + /* Configure the pin as a push-pull GPIO output */ + am_hal_gpio_pin_config(psLED->GPIONumber, AM_HAL_GPIO_OUTPUT); + + /* Enable the output driver, and set the output value to the LEDs "ON" state */ + am_hal_gpio_out_enable_bit_set(psLED->GPIONumber); + am_hal_gpio_out_bit_replace(psLED->GPIONumber, + psLED->Polarity & + AM_LED_POL_DIRECT_DRIVE_M); + } + else + { + /* Configure the pin as a tri-state GPIO */ + am_hal_gpio_pin_config(psLED->GPIONumber, AM_HAL_GPIO_3STATE); + + /* Disable the output driver, and set the output value to the LEDs "ON" state */ + am_hal_gpio_out_enable_bit_clear(psLED->GPIONumber); + am_hal_gpio_out_bit_replace(psLED->GPIONumber, + psLED->Polarity & + AM_LED_POL_DIRECT_DRIVE_M ); + } +} + +/** + * @brief Configures the necessary pins for an array of LEDs + * + * @param NumLEDs is the total number of LEDs in the array. + * + * This function configures the GPIOs for an array of LEDs. + * + * @return None. + */ +void rt_hw_led_array_init(rt_uint32_t NumLEDs) +{ + /* Loop through the list of LEDs, configuring each one individually */ + for ( int i = 0; i < NumLEDs; i++ ) + { + rt_hw_led_init(i); + } +} + +/** + * @brief Disables an array of LEDs + * + * @param NumLEDs is the total number of LEDs in the array. + * + * This function disables the GPIOs for an array of LEDs. + * + * @return None. + */ +void rt_hw_led_array_disable(rt_uint32_t NumLEDs) +{ + rt_hw_led_t *psLEDs = am_psLEDs; + + /* Loop through the list of LEDs, configuring each one individually */ + for ( int i = 0; i < NumLEDs; i++ ) + { + am_hal_gpio_pin_config((psLEDs + i)->GPIONumber, AM_HAL_GPIO_DISABLE); + } +} + +/** + * @brief Turns on the requested LED. + * + * @param LEDNum is the LED number for the light to turn on. + * + * This function turns on a single LED. + * + * @return None. + */ +void rt_hw_led_on(rt_uint32_t LEDNum) +{ + rt_hw_led_t *psLEDs = am_psLEDs; + + /* Handle Direct Drive Versus 3-State (with pull-up or no buffer) */ + if ( AM_LED_POL_DIRECT_DRIVE_M & psLEDs[LEDNum].Polarity ) + { + /* Set the output to the correct state for the LED */ + am_hal_gpio_out_bit_replace(psLEDs[LEDNum].GPIONumber, + psLEDs[LEDNum].Polarity & + AM_LED_POL_POLARITY_M ); + } + else + { + /* Turn on the output driver for the LED */ + am_hal_gpio_out_enable_bit_set(psLEDs[LEDNum].GPIONumber); + } +} + +/** + * @brief Turns off the requested LED. + * + * @param LEDNum is the LED number for the light to turn off. + * + * This function turns off a single LED. + * + * @return None. + */ +void rt_hw_led_off(rt_uint32_t LEDNum) +{ + rt_hw_led_t *psLEDs = am_psLEDs; + + /* Handle Direct Drive Versus 3-State (with pull-up or no buffer) */ + if ( AM_LED_POL_DIRECT_DRIVE_M & psLEDs[LEDNum].Polarity ) + { + /* Set the output to the correct state for the LED */ + am_hal_gpio_out_bit_replace(psLEDs[LEDNum].GPIONumber, + !(psLEDs[LEDNum].Polarity & + AM_LED_POL_POLARITY_M) ); + } + else + { + /* Turn off the output driver for the LED */ + am_hal_gpio_out_enable_bit_clear(psLEDs[LEDNum].GPIONumber); + } +} + +/** + * @brief Toggles the requested LED. + * + * @param LEDNum is the LED number for the light to toggle. + * + * This function toggles a single LED. + * + * @return None. + */ +void rt_hw_led_toggle(rt_uint32_t LEDNum) +{ + rt_hw_led_t *psLEDs = am_psLEDs; + + /* Handle Direct Drive Versus 3-State (with pull-up or no buffer) */ + if ( AM_LED_POL_DIRECT_DRIVE_M & psLEDs[LEDNum].Polarity ) + { + am_hal_gpio_out_bit_toggle(psLEDs[LEDNum].GPIONumber); + } + else + { + /* Check to see if the LED pin is enabled */ + if ( am_hal_gpio_out_enable_bit_get(psLEDs[LEDNum].GPIONumber) ) + { + /* If it was enabled, turn if off */ + am_hal_gpio_out_enable_bit_clear(psLEDs[LEDNum].GPIONumber); + } + else + { + /* If it was not enabled, turn if on */ + am_hal_gpio_out_enable_bit_set(psLEDs[LEDNum].GPIONumber); + } + } +} + +/** + * @brief Gets the state of the requested LED. + * + * @param LEDNum is the LED to check. + * + * This function checks the state of a single LED. + * + * @return 1(true) if the LED is on. + */ +int rt_hw_led_get(rt_uint32_t LEDNum) +{ + rt_hw_led_t *psLEDs = am_psLEDs; + + /* Handle Direct Drive Versus 3-State (with pull-up or no buffer) */ + if ( AM_LED_POL_DIRECT_DRIVE_M & psLEDs[LEDNum].Polarity ) + { + /* Mask to the GPIO bit position for this GPIO number */ + uint64_t ui64Mask = 0x01l << psLEDs[LEDNum].GPIONumber; + + /* Extract the state of this bit and return it */ + return !!(am_hal_gpio_input_read() & ui64Mask); + } + else + { + return am_hal_gpio_out_enable_bit_get( + psLEDs[LEDNum].GPIONumber); + } +} + +/** + * @brief Display a binary value using LEDs. + * + * @param NumLEDs is the number of LEDs in the array. + * @param Value is the value to display on the LEDs. + * + * This function displays a value in binary across an array of LEDs. + * + * @return None. + */ +void rt_hw_led_array_out(rt_uint32_t NumLEDs, rt_uint32_t Value) +{ + for ( int i = 0; i < NumLEDs; i++ ) + { + if ( Value & (1 << i) ) + { + rt_hw_led_on(i); + } + else + { + rt_hw_led_off(i); + } + } +} + +#ifdef RT_USING_FINSH +#include +static rt_uint8_t led_inited = 0; +void led(rt_uint32_t led, rt_uint32_t value) +{ + /* init led configuration if it's not inited. */ + if (!led_inited) + { +// rt_hw_led_init(0); +// rt_hw_led_init(1); + led_inited = 1; + } + + if ( led == 0 ) + { + /* set led status */ + switch (value) + { + case 0: + rt_hw_led_off(0); + break; + case 1: + rt_hw_led_on(0); + break; + default: + break; + } + } + + if ( led == 1 ) + { + /* set led status */ + switch (value) + { + case 0: + rt_hw_led_off(1); + break; + case 1: + rt_hw_led_on(1); + break; + default: + break; + } + } +} +FINSH_FUNCTION_EXPORT(led, set led[0 - 1] on[1] or off[0].) +#endif + +/*@}*/ diff --git a/bsp/apollo2/board/hw_led.h b/bsp/apollo2/board/hw_led.h new file mode 100644 index 0000000000..8f954a7705 --- /dev/null +++ b/bsp/apollo2/board/hw_led.h @@ -0,0 +1,60 @@ +/* + * File : hw_led.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2017, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2017-09-14 Haley the first version + */ + +#ifndef __HW_LED_H +#define __HW_LED_H + +#include + +/** + * @brief LED polarity macros + * + */ +#define AM_LED_POL_POLARITY_M 0x1 +#define AM_LED_ON_HIGH 0x1 +#define AM_LED_ON_LOW 0x0 + +/** + * @brief LED direct drive indicator macro + * Or this in with the polarity value to use the GPIO DATA register instead of + * the GPIO DATA ENABLE register to directly drive an LED buffer. + */ +#define AM_LED_POL_DIRECT_DRIVE_M 0x2 + + +/** + * @brief Structure for keeping track of LEDs + * + */ +typedef struct +{ + rt_uint32_t GPIONumber; + rt_uint32_t Polarity; +} +rt_hw_led_t; + +/** + * @brief External function definitions + * + */ +void rt_hw_led_init(rt_uint32_t LEDNum); +void rt_hw_led_array_init(rt_uint32_t NumLEDs); +void rt_hw_led_array_disable(rt_uint32_t NumLEDs); +void rt_hw_led_on(rt_uint32_t LEDNum); +void rt_hw_led_off(rt_uint32_t LEDNum); +void rt_hw_led_toggle(rt_uint32_t LEDNum); +int rt_hw_led_get(rt_uint32_t LEDNum); +void rt_hw_led_array_out(rt_uint32_t NumLEDs, rt_uint32_t Value); + +#endif // __HW_LED_H diff --git a/bsp/apollo2/board/hw_uart.c b/bsp/apollo2/board/hw_uart.c new file mode 100644 index 0000000000..d1fa7af771 --- /dev/null +++ b/bsp/apollo2/board/hw_uart.c @@ -0,0 +1,413 @@ +/* + * File : hw_uart.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2017, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2017-09-15 Haley the first version + */ + +#include "am_mcu_apollo.h" +#include "hw_uart.h" +#include "board.h" +#include + +/* USART0 */ +#define AM_UART0_INST 0 + +#define UART0_GPIO_RX 2 +#define UART0_GPIO_CFG_RX AM_HAL_PIN_2_UART0RX +#define UART0_GPIO_TX 1 +#define UART0_GPIO_CFG_TX AM_HAL_PIN_1_UART0TX + +/* USART1 */ +#define AM_UART1_INST 1 + +#define UART1_GPIO_RX 9 +#define UART1_GPIO_CFG_RX AM_HAL_PIN_9_UART1RX +#define UART1_GPIO_TX 8 +#define UART1_GPIO_CFG_TX AM_HAL_PIN_8_UART1TX + +/* AM uart driver */ +struct am_uart +{ + uint32_t uart_device; + uint32_t uart_interrupt; +}; + +/** + * @brief UART configuration settings + * + */ +am_hal_uart_config_t g_sUartConfig = +{ + .ui32BaudRate = 115200, + .ui32DataBits = AM_HAL_UART_DATA_BITS_8, + .bTwoStopBits = false, + .ui32Parity = AM_HAL_UART_PARITY_NONE, + .ui32FlowCtrl = AM_HAL_UART_FLOW_CTRL_NONE, +}; + +/** + * @brief Enable the UART + * + * @param Uart driver + * + * This function is Enable the UART + * + * @return None. + */ +static void rt_hw_uart_enable(struct am_uart* uart) +{ + /* Enable the UART clock */ + am_hal_uart_clock_enable(uart->uart_device); + + /* Enable the UART */ + am_hal_uart_enable(uart->uart_device); + +#if defined(RT_USING_UART0) + /* Make sure the UART RX and TX pins are enabled */ + am_hal_gpio_pin_config(UART0_GPIO_TX, UART0_GPIO_CFG_TX); + am_hal_gpio_pin_config(UART0_GPIO_RX, UART0_GPIO_CFG_RX | AM_HAL_GPIO_PULL12K); +#endif /* RT_USING_UART0 */ + +#if defined(RT_USING_UART1) + /* Make sure the UART RX and TX pins are enabled */ + am_hal_gpio_pin_config(UART1_GPIO_TX, UART1_GPIO_CFG_TX); + am_hal_gpio_pin_config(UART1_GPIO_RX, UART1_GPIO_CFG_RX | AM_HAL_GPIO_PULL12K); +#endif /* RT_USING_UART1 */ +} + +/** + * @brief Disable the UART + * + * @param Uart driver + * + * This function is Disable the UART + * + * @return None. + */ +static void rt_hw_uart_disable(struct am_uart* uart) +{ + /* Clear all interrupts before sleeping as having a pending UART interrupt burns power */ + am_hal_uart_int_clear(uart->uart_device, 0xFFFFFFFF); + + /* Disable the UART */ + am_hal_uart_disable(uart->uart_device); + +#if defined(RT_USING_UART0) + /* Disable the UART pins */ + am_hal_gpio_pin_config(UART0_GPIO_TX, AM_HAL_PIN_DISABLE); + am_hal_gpio_pin_config(UART0_GPIO_RX, AM_HAL_PIN_DISABLE); +#endif /* RT_USING_UART0 */ + +#if defined(RT_USING_UART1) + /* Disable the UART pins */ + am_hal_gpio_pin_config(UART1_GPIO_TX, AM_HAL_PIN_DISABLE); + am_hal_gpio_pin_config(UART1_GPIO_RX, AM_HAL_PIN_DISABLE); +#endif /* RT_USING_UART1 */ + + /* Disable the UART clock */ + am_hal_uart_clock_disable(uart->uart_device); +} + +/** + * @brief UART-based string print function. + * + * @param Send buff + * + * This function is used for printing a string via the UART, which for some + * MCU devices may be multi-module. + * + * @return None. + */ +void rt_hw_uart_send_string(char *pcString) +{ + am_hal_uart_string_transmit_polled(AM_UART0_INST, pcString); + + /* Wait until busy bit clears to make sure UART fully transmitted last byte */ + while ( am_hal_uart_flags_get(AM_UART0_INST) & AM_HAL_UART_FR_BUSY ); +} + +static rt_err_t am_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + struct am_uart* uart; + + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + + uart = (struct am_uart *)serial->parent.user_data; + + RT_ASSERT(uart != RT_NULL); + + /* Get the configure */ + g_sUartConfig.ui32BaudRate = cfg->baud_rate; + g_sUartConfig.ui32DataBits = cfg->data_bits; + + if (cfg->stop_bits == STOP_BITS_1) + g_sUartConfig.bTwoStopBits = false; + else if (cfg->stop_bits == STOP_BITS_2) + g_sUartConfig.bTwoStopBits = true; + + g_sUartConfig.ui32Parity = cfg->parity; + g_sUartConfig.ui32FlowCtrl = AM_HAL_UART_PARITY_NONE; + + /* Configure the UART */ + am_hal_uart_config(uart->uart_device, &g_sUartConfig); + + /* Enable the UART */ + am_hal_uart_enable(uart->uart_device); + + return RT_EOK; +} + +static rt_err_t am_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct am_uart* uart; + //rt_uint32_t ctrl_arg = (rt_uint32_t)(arg); + + RT_ASSERT(serial != RT_NULL); + uart = (struct am_uart *)serial->parent.user_data; + + RT_ASSERT(uart != RT_NULL); + + switch (cmd) + { + /* disable interrupt */ + case RT_DEVICE_CTRL_CLR_INT: + rt_hw_uart_disable(uart); + break; + /* enable interrupt */ + case RT_DEVICE_CTRL_SET_INT: + rt_hw_uart_enable(uart); + break; + /* UART config */ + case RT_DEVICE_CTRL_CONFIG : + break; + } + + return RT_EOK; +} + +static int am_putc(struct rt_serial_device *serial, char c) +{ + struct am_uart* uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct am_uart *)serial->parent.user_data; + + RT_ASSERT(uart != RT_NULL); + + am_hal_uart_char_transmit_polled(uart->uart_device, c); + + return 1; +} + +static int am_getc(struct rt_serial_device *serial) +{ + char c; + int ch; + struct am_uart* uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct am_uart *)serial->parent.user_data; + + RT_ASSERT(uart != RT_NULL); + + ch = -1; + if (am_hal_uart_flags_get(uart->uart_device) & AM_HAL_UART_FR_RX_FULL) + { + am_hal_uart_char_receive_polled(uart->uart_device, &c); + ch = c & 0xff; + } + + return ch; +} + +/** + * Uart common interrupt process. This need add to uart ISR. + * + * @param serial serial device + */ +static void uart_isr(struct rt_serial_device *serial) +{ + uint32_t status; + + RT_ASSERT(serial != RT_NULL); + struct am_uart *uart = (struct am_uart *) serial->parent.user_data; + + RT_ASSERT(uart != RT_NULL); + + /* Read the interrupt status */ + status = am_hal_uart_int_status_get(uart->uart_device, false); + + //rt_kprintf("status is %d\r\n", status); + + /* Clear the UART interrupt */ + am_hal_uart_int_clear(uart->uart_device, status); + + if (status & (AM_HAL_UART_INT_RX_TMOUT)) + { + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_TIMEOUT); + } + + if (status & AM_HAL_UART_INT_RX) + { + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); + } + + if (status & AM_HAL_UART_INT_TX) + { + //rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE); + } +} + +static const struct rt_uart_ops am_uart_ops = +{ + am_configure, + am_control, + am_putc, + am_getc, +}; + +#if defined(RT_USING_UART0) +/* UART0 device driver structure */ +struct am_uart uart0 = +{ + AM_UART0_INST, + AM_HAL_INTERRUPT_UART0 +}; +static struct rt_serial_device serial0; + +void am_uart0_isr(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial0); + + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif /* RT_USING_UART0 */ + +#if defined(RT_USING_UART1) +/* UART1 device driver structure */ +struct am_uart uart1 = +{ + AM_UART1_INST, + AM_HAL_INTERRUPT_UART1 +}; +static struct rt_serial_device serial1; + +void am_uart1_isr(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial1); + + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif /* RT_USING_UART1 */ + +static void GPIO_Configuration(void) +{ +#if defined(RT_USING_UART0) + /* Make sure the UART RX and TX pins are enabled */ + am_hal_gpio_pin_config(UART0_GPIO_TX, UART0_GPIO_CFG_TX); + am_hal_gpio_pin_config(UART0_GPIO_RX, UART0_GPIO_CFG_RX | AM_HAL_GPIO_PULL12K); +#endif /* RT_USING_UART0 */ + +#if defined(RT_USING_UART1) + /* Make sure the UART RX and TX pins are enabled */ + am_hal_gpio_pin_config(UART1_GPIO_TX, UART1_GPIO_CFG_TX); + am_hal_gpio_pin_config(UART1_GPIO_RX, UART1_GPIO_CFG_RX | AM_HAL_GPIO_PULL12K); +#endif /* RT_USING_UART1 */ +} + +static void RCC_Configuration(struct am_uart* uart) +{ + /* Power on the selected UART */ + am_hal_uart_pwrctrl_enable(uart->uart_device); + + /* Start the UART interface, apply the desired configuration settings */ + am_hal_uart_clock_enable(uart->uart_device); + + /* Disable the UART before configuring it */ + am_hal_uart_disable(uart->uart_device); + + /* Configure the UART */ + am_hal_uart_config(uart->uart_device, &g_sUartConfig); + + /* Enable the UART */ + am_hal_uart_enable(uart->uart_device); + + /* Enable the UART FIFO */ + //am_hal_uart_fifo_config(uart->uart_device, AM_HAL_UART_TX_FIFO_1_2 | AM_HAL_UART_RX_FIFO_1_2); +} + +static void NVIC_Configuration(struct am_uart* uart) +{ + /* Enable interrupts */ + am_hal_uart_int_enable(uart->uart_device, AM_HAL_UART_INT_RX); + + /* Enable the uart interrupt in the NVIC */ + am_hal_interrupt_enable(uart->uart_interrupt); + am_hal_uart_int_clear(uart->uart_device, 0xFFFFFFFF); +} + +/** + * @brief Initialize the UART + * + * This function initialize the UART + * + * @return None. + */ +void rt_hw_uart_init(void) +{ + struct am_uart* uart; + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + + GPIO_Configuration(); + +#if defined(RT_USING_UART0) + uart = &uart0; + config.baud_rate = BAUD_RATE_115200; + + RCC_Configuration(uart); + NVIC_Configuration(uart); + + serial0.ops = &am_uart_ops; + serial0.config = config; + + /* register UART1 device */ + rt_hw_serial_register(&serial0, "uart0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | + RT_DEVICE_FLAG_INT_TX, uart); +#endif /* RT_USING_UART0 */ + +#if defined(RT_USING_UART1) + uart = &uart1; + config.baud_rate = BAUD_RATE_115200; + + RCC_Configuration(uart); + NVIC_Configuration(uart); + + serial1.ops = &am_uart_ops; + serial1.config = config; + + /* register UART1 device */ + rt_hw_serial_register(&serial1, "uart1", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | + RT_DEVICE_FLAG_INT_TX, uart); +#endif /* RT_USING_UART1 */ +} + +/*@}*/ diff --git a/bsp/apollo2/board/hw_uart.h b/bsp/apollo2/board/hw_uart.h new file mode 100644 index 0000000000..afef169804 --- /dev/null +++ b/bsp/apollo2/board/hw_uart.h @@ -0,0 +1,23 @@ +/* + * File : hw_uart.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2017, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2017-09-14 Haley the first version + */ + +#ifndef __HW_UART_H_ +#define __HW_UART_H_ + +#include + +void rt_hw_uart_init(void); +void rt_hw_uart_send_string(char *pcString); + +#endif // __HW_UART_H_ diff --git a/bsp/apollo2/libraries/SConscript b/bsp/apollo2/libraries/SConscript new file mode 100644 index 0000000000..744d8d7821 --- /dev/null +++ b/bsp/apollo2/libraries/SConscript @@ -0,0 +1,14 @@ +# for module compiling +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/bsp/apollo2/libraries/drivers/SConscript b/bsp/apollo2/libraries/drivers/SConscript new file mode 100644 index 0000000000..c190a8d8be --- /dev/null +++ b/bsp/apollo2/libraries/drivers/SConscript @@ -0,0 +1,29 @@ +import rtconfig +Import('RTT_ROOT') +from building import * + +# get current directory +cwd = GetCurrentDir() + +src = Split(""" +hal/am_hal_clkgen.c +hal/am_hal_debug.c +hal/am_hal_cachectrl.c +hal/am_hal_pwrctrl.c +hal/am_hal_sysctrl.c +hal/am_hal_stimer.c +hal/am_hal_ctimer.c +hal/am_hal_rtc.c +hal/am_hal_interrupt.c +hal/am_hal_queue.c +hal/am_hal_vcomp.c +hal/am_hal_flash.c +hal/am_hal_gpio.c +hal/am_hal_uart.c +""") + +path = [cwd] + +group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path) + +Return('group') diff --git a/bsp/apollo2/libraries/drivers/am_mcu_apollo.h b/bsp/apollo2/libraries/drivers/am_mcu_apollo.h new file mode 100644 index 0000000000..bf46aa61bb --- /dev/null +++ b/bsp/apollo2/libraries/drivers/am_mcu_apollo.h @@ -0,0 +1,132 @@ +//***************************************************************************** +// +//! @file +//! +//! @brief Top Include for Apollo2 class devices. +//! +//! This file provides all the includes necessary for an apollo device. +//! +//! @addtogroup hal Hardware Abstraction Layer (HAL) +// +//! @defgroup apollo2hal HAL for Apollo2 +//! @ingroup hal +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_MCU_APOLLO_H +#define AM_MCU_APOLLO_H + +//***************************************************************************** +// +// C99 +// +//***************************************************************************** +#include +#include +#include +#include +#ifdef __IAR_SYSTEMS_ICC__ +#include "intrinsics.h" // __CLZ() and other intrinsics +#endif + +//***************************************************************************** +// +// Registers +// +//***************************************************************************** +#include "regs/am_reg_base_addresses.h" + +#include "regs/am_reg_macros.h" + +#include "regs/am_reg_adc.h" +#include "regs/am_reg_cachectrl.h" +#include "regs/am_reg_clkgen.h" +#include "regs/am_reg_ctimer.h" +#include "regs/am_reg_gpio.h" +#include "regs/am_reg_iomstr.h" +#include "regs/am_reg_ioslave.h" +#include "regs/am_reg_itm.h" +#include "regs/am_reg_jedec.h" +#include "regs/am_reg_mcuctrl.h" +#include "regs/am_reg_nvic.h" +#include "regs/am_reg_pdm.h" +#include "regs/am_reg_pwrctrl.h" +#include "regs/am_reg_rstgen.h" +#include "regs/am_reg_rtc.h" +#include "regs/am_reg_sysctrl.h" +#include "regs/am_reg_systick.h" +#include "regs/am_reg_tpiu.h" +#include "regs/am_reg_uart.h" +#include "regs/am_reg_vcomp.h" +#include "regs/am_reg_wdt.h" + +//***************************************************************************** +// +// HAL +// +//***************************************************************************** +#include "hal/am_hal_adc.h" +#include "hal/am_hal_cachectrl.h" +#include "hal/am_hal_clkgen.h" +#include "hal/am_hal_ctimer.h" +#include "hal/am_hal_debug.h" +#include "hal/am_hal_flash.h" +#include "hal/am_hal_global.h" +#include "hal/am_hal_gpio.h" +#include "hal/am_hal_i2c_bit_bang.h" +#include "hal/am_hal_interrupt.h" +#include "hal/am_hal_iom.h" +#include "hal/am_hal_ios.h" +#include "hal/am_hal_itm.h" +#include "hal/am_hal_mcuctrl.h" +#include "hal/am_hal_otp.h" +#include "hal/am_hal_pdm.h" +#include "hal/am_hal_pin.h" +#include "hal/am_hal_pwrctrl.h" +#include "hal/am_hal_queue.h" +#include "hal/am_hal_reset.h" +#include "hal/am_hal_rtc.h" +#include "hal/am_hal_stimer.h" +#include "hal/am_hal_sysctrl.h" +#include "hal/am_hal_systick.h" +#include "hal/am_hal_tpiu.h" +#include "hal/am_hal_uart.h" +#include "hal/am_hal_vcomp.h" +#include "hal/am_hal_wdt.h" + +#endif // AM_MCU_APOLLO_H + diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_adc.c b/bsp/apollo2/libraries/drivers/hal/am_hal_adc.c new file mode 100644 index 0000000000..957408d0e5 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_adc.c @@ -0,0 +1,553 @@ +//***************************************************************************** +// +// am_hal_adc.c +//! @file +//! +//! @brief Functions for interfacing with the Analog to Digital Converter. +//! +//! @addtogroup adc2 Analog-to-Digital Converter (ADC) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +//! @brief Private SRAM view of temperature trims. +//! +//! This static SRAM union is private to the ADC HAL functions. +// +//***************************************************************************** +static union +{ + //! These trim values are loaded as uint32_t values. + struct + { + //! Temperature of the package test head (in degrees Kelvin) + uint32_t ui32CalibrationTemperature; + + //! Voltage corresponding to temperature measured on test head. + uint32_t ui32CalibrationVoltage; + + //! ADC offset voltage measured on the package test head. + uint32_t ui32CalibrationOffset; + + //! Flag if default (guess) or measured. + bool bMeasured; + } ui32; + //! These trim values are accessed as floats when used in temp calculations. + struct + { + //! Temperature of the package test head in degrees Kelvin + float fCalibrationTemperature; + + //! Voltage corresponding to temperature measured on test head. + float fCalibrationVoltage; + + //! ADC offset voltage measured on the package test head. + float fCalibrationOffset; + + //! Flag if default (guess) or measured. + float fMeasuredFlag; + } flt; +} priv_temp_trims; + +//***************************************************************************** +// +//! @brief Configure the ADC. +//! +//! @param psConfig - pointer to the configuration structure for the ADC. +//! +//! This function may be used to perform the initial setup of the ADC based on +//! setting found in a configuration structure. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_adc_config(am_hal_adc_config_t *psConfig) +{ + // + // Set general ADC configuration parameters. + // + AM_REG(ADC, CFG) = (psConfig->ui32Clock | + psConfig->ui32TriggerConfig | + psConfig->ui32Reference | + psConfig->ui32ClockMode | + psConfig->ui32PowerMode | + psConfig->ui32Repeat | + AM_REG_ADC_CFG_ADCEN(1)); + + // + // Grab the temperature trims. + // + priv_temp_trims.ui32.ui32CalibrationTemperature = + am_hal_flash_load_ui32(AM_HAL_ADC_CALIB_TEMP_ADDR); + priv_temp_trims.ui32.ui32CalibrationVoltage = + am_hal_flash_load_ui32(AM_HAL_ADC_CALIB_AMBIENT_ADDR); + priv_temp_trims.ui32.ui32CalibrationOffset = + am_hal_flash_load_ui32(AM_HAL_ADC_CALIB_ADC_OFFSET_ADDR); + + if ( (priv_temp_trims.ui32.ui32CalibrationTemperature == 0xffffffff) || + (priv_temp_trims.ui32.ui32CalibrationVoltage == 0xffffffff) || + (priv_temp_trims.ui32.ui32CalibrationOffset == 0xffffffff) ) + { + // + // Since the device has not been calibrated on the tester, we'll load + // default calibration values. These default values should result + // in worst-case temperature measurements of +-6 degress C. + // + priv_temp_trims.flt.fCalibrationTemperature = AM_HAL_ADC_CALIB_TEMP_DEFAULT; + priv_temp_trims.flt.fCalibrationVoltage = AM_HAL_ADC_CALIB_AMBIENT_DEFAULT; + priv_temp_trims.flt.fCalibrationOffset = AM_HAL_ADC_CALIB_ADC_OFFSET_DEFAULT; + priv_temp_trims.ui32.bMeasured = false; + } + else + { + priv_temp_trims.ui32.bMeasured = true; + } +} + +//***************************************************************************** +// +//! @brief Get the temperature trim parameters after configuring the ADC. +//! +//! @param pfTemp - pointer to a location to store the calibration temperature. +//! @param pfVoltage - pointer to a location to store the calibration voltage. +//! @param pfOffsetV - pointer to a location to store the calibration offset. +//! +//! This function may be used to access the actual temperature sensor trim +//! values from the private structure. +//! +//! WARNING: only call this after the ADC has been configured with +//! am_hal_adc_config. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_adc_temp_trims_get(float * pfTemp, float * pfVoltage, float * pfOffsetV) +{ + // + // Return trim temperature as a float, if you can. + // + if ( pfTemp != NULL ) + { + *pfTemp = priv_temp_trims.flt.fCalibrationTemperature; + } + + // + // Return trim voltage as a float, if you can. + // + if ( pfVoltage != NULL ) + { + *pfVoltage = priv_temp_trims.flt.fCalibrationVoltage; + } + + // + // Return trim ADC offset voltage as a float, if you can. + // + if ( pfOffsetV != NULL ) + { + *pfOffsetV = priv_temp_trims.flt.fCalibrationOffset; + } +} + +//***************************************************************************** +// +//! @brief Set the ADC window parameters. +//! +//! @param ui32Upper - the upper limit for the ADC window. +//! @param ui32Upper - the lower limit for the ADC window. +//! +//! This function may be used to change the ADC window parameters. Please note +//! that the upper and lower limits are only 16-bits wide in the ADC hardware. +//! This function will ignore the upper 16 bits of these arguments. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_adc_window_set(uint32_t ui32Upper, uint32_t ui32Lower) +{ + // + // Set the window limits for the ADC. + // + AM_BFW(ADC, WULIM, ULIM, ui32Upper); + AM_BFW(ADC, WLLIM, LLIM, ui32Lower); +} + +//***************************************************************************** +// +//! @brief Configure a single ADC slot. +//! +//! @param ui32SlotNumber - the number of the ADC slot to be configured. +//! @param ui32SlotConfig - contains slot-specific options. +//! +//! This function may be used to configure the settings for an individual ADC +//! slot. The parameter \b ui32SlotConfig should be the logical 'OR' of a slot +//! average macro, a slot hold-time macro, a slot channel macro, and +//! optionally, the slot window enable macro. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_adc_slot_config(uint32_t ui32SlotNumber, uint32_t ui32SlotConfig) +{ + uint32_t ui32RegOffset; + + // + // Make sure we're accessing a real slot. + // + am_hal_debug_assert_msg((ui32SlotNumber & 0xFFFFFFFF0) == 0, + "Trying to configure an ADC slot that doesn't exist."); + + // + // Locate the correct register for this ADC slot. + // + ui32RegOffset = (AM_REG_ADCn(0) + AM_REG_ADC_SL0CFG_O + (4 * ui32SlotNumber)); + + // + // Write the register with the caller's configuration value. + // + AM_REGVAL(ui32RegOffset) = ui32SlotConfig; +} + +//***************************************************************************** +// +//! @brief Peek at the next fifo entry. +//! +//! This function reads the oldest value in the ADC sample fifo but doesn't +//! actually advance the fifo to the next entry. This function is useful when +//! you need information from the fifo but you don't want to also empty the +//! fifo. This could be helpful if you want to check the FIFO depth without +//! pulling any data out. +//! +//! The value returned by this function is the raw 32-bit value provided by the +//! ADC hardware. In order to interpret this value, you will need to use one of +//! the following macros. +//! +//! @return 32-bit FIFO entry. +//! +// +//***************************************************************************** +uint32_t +am_hal_adc_fifo_peek(void) +{ + uint32_t ui32FIFOValue; + + // + // Grab a value from the ADC FIFO. + // + ui32FIFOValue = AM_REG(ADC, FIFO); + + // + // Return FIFO entry. + // + return ui32FIFOValue; +} + +//***************************************************************************** +// +//! @brief +//! +//! This function reads the oldest value in the ADC fifo and then pops the +//! fifo. Use this function when you actually want to pull data out of the +//! fifo. +//! +//! @return 32-bit FIFO entry. +//! +// +//***************************************************************************** +uint32_t +am_hal_adc_fifo_pop(void) +{ + uint32_t ui32FIFOValue; + + // + // Grab a value from the ADC FIFO. + // + ui32FIFOValue = AM_REG(ADC, FIFO); + + // + // Pop the FIFO. + // + AM_REG(ADC, FIFO) = 0; + + // + // Return FIFO valid bits. + // + return ui32FIFOValue; +} + +//***************************************************************************** +// +//! @brief Issue Software Trigger to the ADC. +//! +//! This function issues the software trigger to the ADC. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_adc_trigger(void) +{ + // + // Write to the Software trigger register in the ADC. + // + AM_REG(ADC, SWT) = 0x37; +} + +//***************************************************************************** +// +//! @brief Enable the ADC. +//! +//! Use this function to enable the ADC. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_adc_enable(void) +{ + // + // Enable the ADC. + // + AM_BFW(ADC, CFG, ADCEN, 0x1); +} + +//***************************************************************************** +// +//! @brief Disable the ADC. +//! +//! Use this function to disable the ADC. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_adc_disable(void) +{ + // + // Disable the ADC. + // + AM_BFW(ADC, CFG, ADCEN, 0x0); +} + +//***************************************************************************** +// +//! @brief Enable selected ADC Interrupts. +//! +//! @param ui32Interrupt - Use the macro bit fields provided in am_hal_adc.h. +//! +//! Use this function to enable the ADC interrupts. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_adc_int_enable(uint32_t ui32Interrupt) +{ + // + // Enable the interrupts. + // + AM_REG(ADC, INTEN) |= ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Return enabled ADC Interrupts. +//! +//! Use this function to get all enabled ADC interrupts. +//! +//! @return enabled ADC Interrupts. +// +//***************************************************************************** +uint32_t +am_hal_adc_int_enable_get(void) +{ + // + // Return enabled interrupts. + // + return AM_REG(ADC, INTEN); +} + +//***************************************************************************** +// +//! @brief Disable selected ADC Interrupts. +//! +//! @param ui32Interrupt - Use the macro bit fields provided in am_hal_adc.h. +//! +//! Use this function to disable the ADC interrupts. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_adc_int_disable(uint32_t ui32Interrupt) +{ + // + // Disable the interrupts. + // + AM_REG(ADC, INTEN) &= ~ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Clear selected ADC Interrupts. +//! +//! @param ui32Interrupt - Use the macro bit fields provided in am_hal_adc.h. +//! +//! Use this function to clear the ADC interrupts. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_adc_int_clear(uint32_t ui32Interrupt) +{ + // + // Clear the interrupts. + // + AM_REG(ADC, INTCLR) = ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Set selected ADC Interrupts. +//! +//! @param ui32Interrupt - Use the macro bit fields provided in am_hal_adc.h. +//! +//! Use this function to set the ADC interrupts. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_adc_int_set(uint32_t ui32Interrupt) +{ + // + // Set the interrupts. + // + AM_REG(ADC, INTSET) = ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Return either enabled or raw selected ADC interrupt status. +//! +//! @param bEnabledOnly - return the status of only the enabled interrupts. +//! +//! Use this function to get the ADC interrupt status. +//! +//! @return enabled or raw ADC interrupt status. +// +//***************************************************************************** +uint32_t +am_hal_adc_int_status_get(bool bEnabledOnly) +{ + // + // Return the status. + // + if (bEnabledOnly) + { + uint32_t u32RetVal = AM_REG(ADC, INTEN); + u32RetVal &= AM_REG(ADC, INTSTAT); + return u32RetVal; + } + else + { + return AM_REG(ADC, INTSTAT); + } +} + +//***************************************************************************** +// +//! @brief Return temperature in degrees C of supplied voltage. +//! +//! @param fVoltage - return the temperature corresponding to this voltage. +//! +//! Use this function to convert volts from the temperature sensor into degrees +//! C. Caller converts ADC binary code to volts based on reference used. +//! This routine looks up the trim parameters and returns corrected temperature. +//! +//! The computation is based on a line running through 0 degrees K. +//! We find the slope from the trimmed temperature calibration point. +//! +//! +//! @return the temperature in degrees C. +// +//***************************************************************************** +float +am_hal_adc_volts_to_celsius(float fVoltage) +{ + float fTemp; + + // + // Get calibration temperature from trimmed values & convert to degrees K. + // + float fCalibration_temp = priv_temp_trims.flt.fCalibrationTemperature; + + // + // Get remaining trimmed values. + // + float fCalibration_voltage = priv_temp_trims.flt.fCalibrationVoltage; + float fCalibration_offset = priv_temp_trims.flt.fCalibrationOffset; + + // + // Compute the temperature. + // + fTemp = fCalibration_temp; + fTemp /= (fCalibration_voltage - fCalibration_offset); + fTemp *= (fVoltage - fCalibration_offset); + + // + // Give it back to the caller in Celsius. + // + return fTemp - 273.15f; +} + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_adc.h b/bsp/apollo2/libraries/drivers/hal/am_hal_adc.h new file mode 100644 index 0000000000..86b48b162c --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_adc.h @@ -0,0 +1,348 @@ +//***************************************************************************** +// +// am_hal_adc.h +//! @file +//! +//! @brief Functions for interfacing with the Analog to Digital Converter +//! +//! @addtogroup adc2 Analog-to-Digital Converter (ADC) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_ADC_H +#define AM_HAL_ADC_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +//! @name Clock Selection +//! @brief These macros may be used to set the ADC module's clock source. +//! @{ +// +//***************************************************************************** +#define AM_HAL_ADC_CLOCK_OFF AM_REG_ADC_CFG_CLKSEL_OFF +#define AM_HAL_ADC_CLOCK_HFRC AM_REG_ADC_CFG_CLKSEL_HFRC +#define AM_HAL_ADC_CLOCK_DIV2 AM_REG_ADC_CFG_CLKSEL_HFRC_DIV2 +//! @} + +//***************************************************************************** +// +//! @name Trigger Settings +//! @brief ADC trigger setting macros. +//! +//! These macros alter the ADC's trigger source and trigger polarity. Note that +//! the external trigger setting needs to be ORed with a POS or NEG option to +//! define the desired trigger polarity. +//! @{ +// +//***************************************************************************** +#define AM_HAL_ADC_TRIGGER_SOFT AM_REG_ADC_CFG_TRIGSEL_SWT +#define AM_HAL_ADC_TRIGGER_VCOMP AM_REG_ADC_CFG_TRIGSEL_VCOMP +#define AM_HAL_ADC_TRIGGER_EXT0 AM_REG_ADC_CFG_TRIGSEL_EXT0 +#define AM_HAL_ADC_TRIGGER_EXT1 AM_REG_ADC_CFG_TRIGSEL_EXT1 +#define AM_HAL_ADC_TRIGGER_EXT2 AM_REG_ADC_CFG_TRIGSEL_EXT2 +#define AM_HAL_ADC_TRIGGER_EXT3 AM_REG_ADC_CFG_TRIGSEL_EXT3 +#define AM_HAL_ADC_TRIGGER_FALL AM_REG_ADC_CFG_TRIGPOL_FALLING_EDGE +#define AM_HAL_ADC_TRIGGER_RISE AM_REG_ADC_CFG_TRIGPOL_RISING_EDGE +//! @} + +//***************************************************************************** +// +//! @name Reference Settings +//! @brief ADC reference voltage setting macros. +//! +//! These macros control the ADC reference voltage source. +//! @{ +// +//***************************************************************************** +#define AM_HAL_ADC_REF_EXT_2P0 AM_REG_ADC_CFG_REFSEL_EXT2P0 +#define AM_HAL_ADC_REF_EXT_1P5 AM_REG_ADC_CFG_REFSEL_EXT1P5 +#define AM_HAL_ADC_REF_INT_2P0 AM_REG_ADC_CFG_REFSEL_INT2P0 +#define AM_HAL_ADC_REF_INT_1P5 AM_REG_ADC_CFG_REFSEL_INT1P5 +//! @} + +//***************************************************************************** +// +//! @name Clock Mode +//! @brief ADC clock mode settings +//! +//! These macros determine whether the ADC shuts down its clock between +//! samples. Shutting down the clock will reduce power consumption, but +//! increase latency. This setting is only valid for LPMODE 0. For other modes, +//! it will be ignored. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_ADC_CK_LOW_POWER AM_REG_ADC_CFG_CKMODE_LPCKMODE +#define AM_HAL_ADC_CK_LOW_LATENCY AM_REG_ADC_CFG_CKMODE_LLCKMODE +//! @} + +//***************************************************************************** +// +//! @name Low Power Mode +//! @brief ADC power conservation settings. +//! +//! These macros select the power state to enter between active scans. Each low +//! power mode has its own set of timing constraints. Please see the datasheet +//! for additional timing information on each power mode. +//! @{ +// +//***************************************************************************** +#define AM_HAL_ADC_LPMODE_0 AM_REG_ADC_CFG_LPMODE_MODE0 +#define AM_HAL_ADC_LPMODE_1 AM_REG_ADC_CFG_LPMODE_MODE1 +//! @} + +//***************************************************************************** +// +//! @name Repeat Mode +//! @brief Enable repeating scan mode. +//! +//! Use this macro to enable repeating scans using timer 3. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_ADC_REPEAT AM_REG_ADC_CFG_RPTEN(1) +#define AM_HAL_ADC_NO_REPEAT AM_REG_ADC_CFG_RPTEN(0) +//! @} + +//***************************************************************************** +// +//! @name Slot configuration +//! @brief Slot configuration macros +//! +//! These macros may be used to configure an individual ADC slot. +//! @{ +// +//***************************************************************************** + +// Set number of samples to average. +#define AM_HAL_ADC_SLOT_AVG_1 AM_REG_ADC_SL0CFG_ADSEL0(0) +#define AM_HAL_ADC_SLOT_AVG_2 AM_REG_ADC_SL0CFG_ADSEL0(1) +#define AM_HAL_ADC_SLOT_AVG_4 AM_REG_ADC_SL0CFG_ADSEL0(2) +#define AM_HAL_ADC_SLOT_AVG_8 AM_REG_ADC_SL0CFG_ADSEL0(3) +#define AM_HAL_ADC_SLOT_AVG_16 AM_REG_ADC_SL0CFG_ADSEL0(4) +#define AM_HAL_ADC_SLOT_AVG_32 AM_REG_ADC_SL0CFG_ADSEL0(5) +#define AM_HAL_ADC_SLOT_AVG_64 AM_REG_ADC_SL0CFG_ADSEL0(6) +#define AM_HAL_ADC_SLOT_AVG_128 AM_REG_ADC_SL0CFG_ADSEL0(7) + +// Set slot precision mode. +#define AM_HAL_ADC_SLOT_14BIT AM_REG_ADC_SL0CFG_PRMODE0_P14B +#define AM_HAL_ADC_SLOT_12BIT AM_REG_ADC_SL0CFG_PRMODE0_P14B +#define AM_HAL_ADC_SLOT_10BIT AM_REG_ADC_SL0CFG_PRMODE0_P14B +#define AM_HAL_ADC_SLOT_8BIT AM_REG_ADC_SL0CFG_PRMODE0_P14B + +// Select a channel by number. +#define AM_HAL_ADC_SLOT_CHANNEL(n) AM_REG_ADC_SL0CFG_CHSEL0(n) + +// Single-ended channels +#define AM_HAL_ADC_SLOT_CHSEL_SE0 AM_REG_ADC_SL0CFG_CHSEL0_SE0 +#define AM_HAL_ADC_SLOT_CHSEL_SE1 AM_REG_ADC_SL0CFG_CHSEL0_SE1 +#define AM_HAL_ADC_SLOT_CHSEL_SE2 AM_REG_ADC_SL0CFG_CHSEL0_SE2 +#define AM_HAL_ADC_SLOT_CHSEL_SE3 AM_REG_ADC_SL0CFG_CHSEL0_SE3 +#define AM_HAL_ADC_SLOT_CHSEL_SE4 AM_REG_ADC_SL0CFG_CHSEL0_SE4 +#define AM_HAL_ADC_SLOT_CHSEL_SE5 AM_REG_ADC_SL0CFG_CHSEL0_SE5 +#define AM_HAL_ADC_SLOT_CHSEL_SE6 AM_REG_ADC_SL0CFG_CHSEL0_SE6 +#define AM_HAL_ADC_SLOT_CHSEL_SE7 AM_REG_ADC_SL0CFG_CHSEL0_SE7 +#define AM_HAL_ADC_SLOT_CHSEL_SE8 AM_REG_ADC_SL0CFG_CHSEL0_SE8 +#define AM_HAL_ADC_SLOT_CHSEL_SE9 AM_REG_ADC_SL0CFG_CHSEL0_SE9 + +// Differential channels. +#define AM_HAL_ADC_SLOT_CHSEL_DF0 AM_REG_ADC_SL0CFG_CHSEL0_DF0 +#define AM_HAL_ADC_SLOT_CHSEL_DF1 AM_REG_ADC_SL0CFG_CHSEL0_DF1 + +// Miscellaneous other signals. +#define AM_HAL_ADC_SLOT_CHSEL_TEMP AM_REG_ADC_SL0CFG_CHSEL0_TEMP +#define AM_HAL_ADC_SLOT_CHSEL_VSS AM_REG_ADC_SL0CFG_CHSEL0_VSS +#define AM_HAL_ADC_SLOT_CHSEL_VBATT AM_REG_ADC_SL0CFG_CHSEL0_BATT + +// Window enable. +#define AM_HAL_ADC_SLOT_WINDOW_EN AM_REG_ADC_SL0CFG_WCEN0(1) + +// Enable the slot. +#define AM_HAL_ADC_SLOT_ENABLE AM_REG_ADC_SL0CFG_SLEN0(1) +//! @} + +//***************************************************************************** +// +//! @name Interrupt Status Bits +//! @brief Interrupt Status Bits for enable/disble use +//! +//! These macros may be used to enable an individual ADC interrupt cause. +//! @{ +// +//***************************************************************************** +#define AM_HAL_ADC_INT_WCINC AM_REG_ADC_INTEN_WCINC(1) +#define AM_HAL_ADC_INT_WCEXC AM_REG_ADC_INTEN_WCEXC(1) +#define AM_HAL_ADC_INT_FIFOOVR2 AM_REG_ADC_INTEN_FIFOOVR2(1) +#define AM_HAL_ADC_INT_FIFOOVR1 AM_REG_ADC_INTEN_FIFOOVR1(1) +#define AM_HAL_ADC_INT_SCNCMP AM_REG_ADC_INTEN_SCNCMP(1) +#define AM_HAL_ADC_INT_CNVCMP AM_REG_ADC_INTEN_CNVCMP(1) +//! @} + +//***************************************************************************** +// +//! @name Temperature Trim Value Locations +//! @brief Temperature calibration cofficients are stored in readable space. +//! +//! These macros are used to access the temperature trim values in readable +//! space. +//! @{ +// +//***************************************************************************** +#define AM_HAL_ADC_CALIB_TEMP_ADDR (0x50023010) +#define AM_HAL_ADC_CALIB_AMBIENT_ADDR (0x50023014) +#define AM_HAL_ADC_CALIB_ADC_OFFSET_ADDR (0x50023018) + +// +// Default coefficients (used when trims not provided): +// TEMP_DEFAULT = Temperature in deg K (e.g. 299.5 - 273.15 = 26.35) +// AMBIENT_DEFAULT = Voltage measurement at default temperature. +// OFFSET_DEFAULT = Default ADC offset at 1v. +// +#define AM_HAL_ADC_CALIB_TEMP_DEFAULT (299.5F) +#define AM_HAL_ADC_CALIB_AMBIENT_DEFAULT (1.02809F) +#define AM_HAL_ADC_CALIB_ADC_OFFSET_DEFAULT (-0.004281F) +//! @} + +//***************************************************************************** +// +//! @brief Configuration structure for the ADC. +// +//***************************************************************************** +typedef struct +{ + //! Select the ADC Clock source using one of the clock source macros. + uint32_t ui32Clock; + + //! Select the ADC trigger source using a trigger source macro. + uint32_t ui32TriggerConfig; + + //! Use a macro to select the ADC reference voltage. + uint32_t ui32Reference; + + //! Use a macro to decide whether to disable clocks between samples. + uint32_t ui32ClockMode; + + //! Use a macro to select the ADC power mode. + uint32_t ui32PowerMode; + + //! Select whether the ADC will re-trigger based on a signal from timer 3. + uint32_t ui32Repeat; +} +am_hal_adc_config_t; + +//***************************************************************************** +// +//! @brief ADC Fifo Read macros +//! +//! These are helper macros for interpreting FIFO data. Each ADC FIFO entry +//! contains information about the slot number and the FIFO depth alongside the +//! current sample. These macros perform the correct masking and shifting to +//! read those values. +//! +//! The SAMPLE and FULL_SAMPLE options refer to the fractional part of averaged +//! samples. If you are not using hardware averaging or don't need the +//! fractional part of the ADC sample, you should just use +//! AM_HAL_ADC_FIFO_SAMPLE. +//! +//! If you do need the fractional part, use AM_HAL_ADC_FIFO_FULL_SAMPLE. This +//! macro will keep six bits of precision past the decimal point. Depending on +//! the number of averaged samples, anywhere between 1 and 6 of these bits will +//! be valid. Please consult the datasheet to find out how many bits of data +//! are valid for your chosen averaging settings. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_ADC_FIFO_SAMPLE(value) \ + ((((value) & AM_REG_ADC_FIFO_DATA_M) >> AM_REG_ADC_FIFO_DATA_S) >> 6) + +#define AM_HAL_ADC_FIFO_FULL_SAMPLE(value) \ + (((value) & AM_REG_ADC_FIFO_DATA_M) >> AM_REG_ADC_FIFO_DATA_S ) + +#define AM_HAL_ADC_FIFO_SLOT(value) \ + (((value) & AM_REG_ADC_FIFO_SLOTNUM_M) >> AM_REG_ADC_FIFO_SLOTNUM_S) + +#define AM_HAL_ADC_FIFO_COUNT(value) \ + (((value) & AM_REG_ADC_FIFO_COUNT_M) >> AM_REG_ADC_FIFO_COUNT_S) +//! @} + +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern void am_hal_adc_config(am_hal_adc_config_t *psConfig); +extern void am_hal_adc_window_set(uint32_t ui32Upper, uint32_t ui32Lower); +extern void am_hal_adc_slot_config(uint32_t ui32SlotNumber, + uint32_t ui32SlotConfig); + +extern uint32_t am_hal_adc_fifo_peek(void); +extern uint32_t am_hal_adc_fifo_pop(void); + +extern void am_hal_adc_trigger(void); +extern void am_hal_adc_enable(void); +extern void am_hal_adc_disable(void); +extern void am_hal_adc_int_enable(uint32_t ui32Interrupt); +extern uint32_t am_hal_adc_int_enable_get(void); +extern void am_hal_adc_int_disable(uint32_t ui32Interrupt); +extern void am_hal_adc_int_clear(uint32_t ui32Interrupt); +extern void am_hal_adc_int_set(uint32_t ui32Interrupt); +extern uint32_t am_hal_adc_int_status_get(bool bEnabledOnly); +extern float am_hal_adc_volts_to_celsius(float fVoltage); +extern void am_hal_adc_temp_trims_get(float * pfTemp, float * pfVoltage, float * pfOffsetV); + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_ADC_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_cachectrl.c b/bsp/apollo2/libraries/drivers/hal/am_hal_cachectrl.c new file mode 100644 index 0000000000..23c7164418 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_cachectrl.c @@ -0,0 +1,576 @@ +//***************************************************************************** +// +// am_hal_cachectrl.c +//! @file +//! +//! @brief Functions for interfacing with the CACHE controller. +//! +//! @addtogroup clkgen2 Clock Generator (CACHE) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +// Default settings for the cache. +// +//***************************************************************************** +const am_hal_cachectrl_config_t am_hal_cachectrl_defaults = +{ + .ui32EnableCache = 1, + .ui32LRU = 0, + .ui32EnableNCregions = 0, + .ui32Config = AM_HAL_CACHECTRL_CACHECFG_CONFIG_2WAY_512, + .ui32SerialCacheMode = 0, + .ui32FlashCachingEnables = 3, + .ui32EnableCacheClockGating = 1, + .ui32EnableLightSleep = 0, + .ui32Dly = 1, + .ui32SMDly = 1, + .ui32EnableDataClockGating = 1, + .ui32EnableCacheMonitoring = 0, +}; + +//***************************************************************************** +// +//! @brief Enable the cache using the supplied settings +//! +//! @param psConfig - pointer to a config structure containing cache settings. +//! +//! This function takes in a structure of cache settings, and uses them to +//! enable the cache. This function will take care of the necessary register +//! writes both in this module and in the power control module, so a separate +//! powerctrl call is not necessary. +//! +//! For most applications, the default cache settings will be the most +//! efficient choice. To use the default cache settings with this function, use +//! the address of the global am_hal_cachectrl_defaults structure as the +//! psConfig argument. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_cachectrl_enable(const am_hal_cachectrl_config_t *psConfig) +{ + uint32_t ui32ConfigValue; + uint32_t ui32Timeout; + + // + // Pull the configuration data from the structure, and prepare to write the + // cache configuration register. + // + // NOTE: ICACHE and DCACHE settings were left out from this step. This is a + // workaround for a timing issue with early versions of Apollo2 that caused + // the cache to incorrectly mark itself valid during the startup sequence. + // The workaround calls for us to start the cache, manually invalidate it, + // and then enable ICACHE and DCACHE operation. + // + ui32ConfigValue = (AM_REG_CACHECTRL_CACHECFG_ENABLE( 1 ) | + AM_REG_CACHECTRL_CACHECFG_LRU( psConfig->ui32LRU ) | + AM_REG_CACHECTRL_CACHECFG_ENABLE_NC0( (psConfig->ui32EnableNCregions & 0x1) >> 0 ) | + AM_REG_CACHECTRL_CACHECFG_ENABLE_NC1( (psConfig->ui32EnableNCregions & 0x2) >> 1 ) | + psConfig->ui32Config | + AM_REG_CACHECTRL_CACHECFG_SERIAL(psConfig->ui32SerialCacheMode) | + AM_REG_CACHECTRL_CACHECFG_CACHE_CLKGATE( psConfig->ui32EnableCacheClockGating ) | + AM_REG_CACHECTRL_CACHECFG_CACHE_LS(psConfig->ui32EnableLightSleep ) | + AM_REG_CACHECTRL_CACHECFG_DLY( psConfig->ui32Dly ) | + AM_REG_CACHECTRL_CACHECFG_SMDLY( psConfig->ui32SMDly ) | + AM_REG_CACHECTRL_CACHECFG_DATA_CLKGATE(psConfig->ui32EnableDataClockGating) | + AM_REG_CACHECTRL_CACHECFG_ENABLE_MONITOR(psConfig->ui32EnableCacheMonitoring) ); + + // + // Make sure the cache is enabled in the power control block. + // + am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEMEN_CACHE); + + // + // Set the initial cache settings. + // + AM_REG(CACHECTRL, CACHECFG) = ui32ConfigValue; + + // + // Wait for the cache ready signal. + // + for (ui32Timeout = 0; ui32Timeout < 50; ui32Timeout++) + { + if (AM_BFM(CACHECTRL, CACHECTRL, CACHE_READY)) + { + break; + } + } + + // + // Manually invalidate the cache (workaround for the issue described above.) + // + AM_BFW(CACHECTRL, CACHECTRL, INVALIDATE, 1); + + // + // Wait for the cache ready signal again. + // + for (ui32Timeout = 0; ui32Timeout < 50; ui32Timeout++) + { + if (AM_BFM(CACHECTRL, CACHECTRL, CACHE_READY)) + { + break; + } + } + + // + // Now that the cache is running, and correctly marked invalid, we can OR in + // the ICACHE and DCACHE settings. + // + ui32ConfigValue |= (AM_REG_CACHECTRL_CACHECFG_ICACHE_ENABLE( (psConfig->ui32FlashCachingEnables & 0x1) >> 0 ) | + AM_REG_CACHECTRL_CACHECFG_DCACHE_ENABLE( (psConfig->ui32FlashCachingEnables & 0x2) >> 1 ) ); + + // + // Write the final configuration settings to the CACHECTRL register. + // + AM_REG(CACHECTRL, CACHECFG) = ui32ConfigValue; +} + +//***************************************************************************** +// +//! @brief Disable the cache. +//! +//! Call this function to completely shut down cache features. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_cachectrl_disable(void) +{ + uint32_t ui32CacheCfg; + + // + // Save the cache settings. + // + ui32CacheCfg = AM_REG(CACHECTRL, CACHECFG); + + // + // Remove the ICACHE and DCACHE settings. + // + ui32CacheCfg &= (AM_REG_CACHECTRL_CACHECFG_DCACHE_ENABLE(0) | + AM_REG_CACHECTRL_CACHECFG_ICACHE_ENABLE(0)); + + // + // Write the resulting value back to the register. + // + AM_REG(CACHECTRL, CACHECFG) = ui32CacheCfg; + + // + // Read the CACHECTRL register a few times + // + AM_REG(CACHECTRL, CACHECTRL); + AM_REG(CACHECTRL, CACHECTRL); + AM_REG(CACHECTRL, CACHECTRL); + + // + // Disable the cache completely. + // + AM_BFW(CACHECTRL, CACHECFG, ENABLE, 0); + + // + // Power the cache down in the powerctrl block. + // + am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEMEN_CACHE_DIS); +} + +//***************************************************************************** +// +//! @brief Set a default cache configuration. +//! +//! This function is used to set a default cache configuration. +// +//***************************************************************************** +void +am_hal_cachectrl_config_default(void) +{ + // + // Set PWRCTRL + // + am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEMEN_CACHE); + + // + // Write a default configuration to the CACHECFG register. + // + AM_REG(CACHECTRL, CACHECFG) = \ + AM_REG_CACHECTRL_CACHECFG_ENABLE( 1 ) | \ + AM_REG_CACHECTRL_CACHECFG_LRU( 0 ) | \ + AM_REG_CACHECTRL_CACHECFG_ENABLE_NC0( 0 ) | \ + AM_REG_CACHECTRL_CACHECFG_ENABLE_NC1( 0 ) | \ + AM_REG_CACHECTRL_CACHECFG_CONFIG_W2_128B_512E | \ + AM_REG_CACHECTRL_CACHECFG_SERIAL( 0 ) | \ + AM_REG_CACHECTRL_CACHECFG_ICACHE_ENABLE( 1 ) | \ + AM_REG_CACHECTRL_CACHECFG_DCACHE_ENABLE( 1 ) | \ + AM_REG_CACHECTRL_CACHECFG_CACHE_CLKGATE( 1 ) | \ + AM_REG_CACHECTRL_CACHECFG_CACHE_LS( 0 ) | \ + AM_REG_CACHECTRL_CACHECFG_DLY( 1 ) | \ + AM_REG_CACHECTRL_CACHECFG_SMDLY( 1 ) | \ + AM_REG_CACHECTRL_CACHECFG_DATA_CLKGATE( 1 ) | \ + AM_REG_CACHECTRL_CACHECFG_ENABLE_MONITOR( 0 ); + + // + // Write a default configuration to the FLASHCFG register. + // + AM_REG(CACHECTRL, FLASHCFG) = AM_REG_CACHECTRL_FLASHCFG_RD_WAIT(1); + + // + // Write a default configuration to the CACHECTRL register. + // + AM_REG(CACHECTRL, CACHECTRL) = \ + AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_ENABLE(1) | \ + AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_DISABLE(0) | \ + AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_ENABLE(1) | \ + AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_DISABLE(0) | \ + AM_REG_CACHECTRL_CACHECTRL_RESET_STAT(0) | \ + AM_REG_CACHECTRL_CACHECTRL_INVALIDATE(0); + + // + // Write a default configuration to the NCR0START and NCR0END registers. + // + AM_REG(CACHECTRL, NCR0START) = \ + AM_REG_CACHECTRL_NCR0START_ADDR(0); + AM_REG(CACHECTRL, NCR0END) = \ + AM_REG_CACHECTRL_NCR0END_ADDR(0); + + // + // Write a default configuration to the NCR1START and NCR1END registers. + // + AM_REG(CACHECTRL, NCR1START) = \ + AM_REG_CACHECTRL_NCR1START_ADDR(0); + AM_REG(CACHECTRL, NCR1END) = \ + AM_REG_CACHECTRL_NCR1END_ADDR(0); + + // + // Write a default configuration to the DMONn and IMONn registers. + // + AM_REG(CACHECTRL, DMON0) = \ + AM_REG_CACHECTRL_DMON0_DACCESS_COUNT(0); + AM_REG(CACHECTRL, DMON1) = \ + AM_REG_CACHECTRL_DMON1_DLOOKUP_COUNT(0); + AM_REG(CACHECTRL, DMON2) = \ + AM_REG_CACHECTRL_DMON2_DHIT_COUNT(0); + AM_REG(CACHECTRL, DMON3) = \ + AM_REG_CACHECTRL_DMON3_DLINE_COUNT(0); + AM_REG(CACHECTRL, IMON0) = \ + AM_REG_CACHECTRL_IMON0_IACCESS_COUNT(0); + AM_REG(CACHECTRL, IMON1) = \ + AM_REG_CACHECTRL_IMON1_ILOOKUP_COUNT(0); + AM_REG(CACHECTRL, IMON2) = \ + AM_REG_CACHECTRL_IMON2_IHIT_COUNT(0); + AM_REG(CACHECTRL, IMON3) = \ + AM_REG_CACHECTRL_IMON3_ILINE_COUNT(0); +} + +//***************************************************************************** +// +//! @brief Enable the flash cache controller via a configuration structure. +//! +//! @param psConfig - Pointer to a data structure containing all of the data +// necessary to configure the CACHECFG register. +//! +//! This function is used to configure all fields of the CACHECFG. +// +//***************************************************************************** +void +am_hal_cachectrl_config(am_hal_cachectrl_config_t *psConfig) +{ + uint32_t u32ConfigValue; + + // + // Arrange all of the members of the data structure into a single u32 that + // can be written to the register. + // + u32ConfigValue = + AM_REG_CACHECTRL_CACHECFG_ENABLE( psConfig->ui32EnableCache ) | + AM_REG_CACHECTRL_CACHECFG_LRU( psConfig->ui32LRU ) | + AM_REG_CACHECTRL_CACHECFG_ENABLE_NC0( + (psConfig->ui32EnableNCregions & 0x1) >> 0 ) | + AM_REG_CACHECTRL_CACHECFG_ENABLE_NC1( + (psConfig->ui32EnableNCregions & 0x2) >> 1 ) | + psConfig->ui32Config | + AM_REG_CACHECTRL_CACHECFG_SERIAL(psConfig->ui32SerialCacheMode) | + AM_REG_CACHECTRL_CACHECFG_ICACHE_ENABLE( + (psConfig->ui32FlashCachingEnables & 0x1) >> 0 ) | + AM_REG_CACHECTRL_CACHECFG_DCACHE_ENABLE( + (psConfig->ui32FlashCachingEnables & 0x2) >> 1 ) | + AM_REG_CACHECTRL_CACHECFG_CACHE_CLKGATE( + psConfig->ui32EnableCacheClockGating ) | + AM_REG_CACHECTRL_CACHECFG_CACHE_LS( + psConfig->ui32EnableLightSleep ) | + AM_REG_CACHECTRL_CACHECFG_DLY( psConfig->ui32Dly ) | + AM_REG_CACHECTRL_CACHECFG_SMDLY( psConfig->ui32SMDly ) | + AM_REG_CACHECTRL_CACHECFG_DATA_CLKGATE( + psConfig->ui32EnableDataClockGating ) | + AM_REG_CACHECTRL_CACHECFG_ENABLE_MONITOR( + psConfig->ui32EnableCacheMonitoring ); + + // + // Write the configuration value to the CACHECFG register. + // + AM_REG(CACHECTRL, CACHECFG) = u32ConfigValue; +} + +//***************************************************************************** +// +//! @brief Configure the various flash cache controller enables. +//! +//! @param u32EnableMask - Mask of features to be enabled. +//! @param u32DisableMask - Mask of features to be disabled. +//! +//! This function is used to enable or disable the various flash cache +//! controller configuration enables which consist of the following: +//! AM_HAL_CACHECTRL_CACHECFG_ENABLE Flash cache controller +//! AM_HAL_CACHECTRL_CACHECFG_LRU_ENABLE LRU (disabled = LRR) +//! AM_HAL_CACHECTRL_CACHECFG_NC0_ENABLE Non-cacheable region 0 +//! AM_HAL_CACHECTRL_CACHECFG_NC1_ENABLE Non-cacheable region 1 +//! AM_HAL_CACHECTRL_CACHECFG_SERIAL_ENABLE Serial cache mode +//! AM_HAL_CACHECTRL_CACHECFG_ICACHE_ENABLE Instruction caching +//! AM_HAL_CACHECTRL_CACHECFG_DCACHE_ENABLE Data caching. +//! AM_HAL_CACHECTRL_CACHECFG_CACHE_CLKGATE_ENABLE Cache clock gating +//! AM_HAL_CACHECTRL_CACHECFG_LS_ENABLE Light sleep cache RAMs +//! AM_HAL_CACHECTRL_CACHECFG_DATA_CLKGATE_ENABLE Data clock gating +//! AM_HAL_CACHECTRL_CACHECFG_MONITOR_ENABLE Cache Monitoring Stats +//! +//! Note that if both an enable and disable are provided in their respective +//! masks, the enable will take precendence. +//! +//! @return The previous status of the flash cache controller enables. +// +//***************************************************************************** +#define CACHECTRL_VALID_ENABLES ( \ + AM_REG_CACHECTRL_CACHECFG_ENABLE_M | \ + AM_REG_CACHECTRL_CACHECFG_LRU_M | \ + AM_REG_CACHECTRL_CACHECFG_ENABLE_NC0_M | \ + AM_REG_CACHECTRL_CACHECFG_ENABLE_NC1_M | \ + AM_REG_CACHECTRL_CACHECFG_SERIAL_M | \ + AM_REG_CACHECTRL_CACHECFG_ICACHE_ENABLE_M | \ + AM_REG_CACHECTRL_CACHECFG_DCACHE_ENABLE_M | \ + AM_REG_CACHECTRL_CACHECFG_CACHE_CLKGATE_M | \ + AM_REG_CACHECTRL_CACHECFG_CACHE_LS_M | \ + AM_REG_CACHECTRL_CACHECFG_DATA_CLKGATE_M | \ + AM_REG_CACHECTRL_CACHECFG_ENABLE_MONITOR_M ) + +uint32_t +am_hal_cachectrl_cache_enables(uint32_t u32EnableMask, uint32_t u32DisableMask) +{ + uint32_t ui32RetVal = AM_BFR(CACHECTRL, CACHECFG, ENABLE) & + CACHECTRL_VALID_ENABLES; + + // + // Make sure the enable masks include only valid bits. + // + u32EnableMask &= CACHECTRL_VALID_ENABLES; + u32DisableMask &= CACHECTRL_VALID_ENABLES; + + // + // First, do the disables. + // + AM_REG(CACHECTRL, CACHECFG) &= ~u32DisableMask; + + // + // Now set the enables. + // + AM_REG(CACHECTRL, CACHECFG) |= u32EnableMask; + + return ui32RetVal; +} + +//***************************************************************************** +// +//! @brief Select the cache configuration type. +//! +//! This functions only sets the CACHECFG CONFIG field. +//! +//! @param ui32CacheConfig - The cache configuration value. +//! +//! This function can be used to select the type of cache.frequency of the main +//! system clock. The ui32CacheConfig parameter should be set to one of the +//! following values: +//! +//! AM_HAL_CACHECTRL_CACHECFG_CONFIG_DIRECT_256 : Direct mapped, +//! 128-bit linesize, 256 entries (2 SRAMs active). +//! AM_HAL_CACHECTRL_CACHECFG_CONFIG_2WAY_256 : Two-way set associative, +//! 128-bit linesize, 256 entries (4 SRAMs active). +//! AM_HAL_CACHECTRL_CACHECFG_CONFIG_2WAY_512 : Two-way set associative, +//! 128-bit linesize, 512 entries (8 SRAMs active). +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_cachectrl_cache_config(uint32_t ui32CacheConfig) +{ + // + // Clear the bitfield + // + AM_REG(CACHECTRL, CACHECFG) &= ~AM_REG_CACHECTRL_CACHECFG_CONFIG_M; + + // + // Write the new value to the bitfield. + // + AM_REG(CACHECTRL, CACHECFG) |= ui32CacheConfig & + AM_REG_CACHECTRL_CACHECFG_CONFIG_M; +} + +//***************************************************************************** +// +//! @brief Invalidate the flash cache. +//! +//! This function is used to invalidate the flash cache. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_cachectrl_invalidate_flash_cache(void) +{ + // + // Write the bit to invalidate the flash cache. + // Note - this bit is not sticky, no need to write it back to 0. + // + AM_REG(CACHECTRL, CACHECTRL) |= AM_REG_CACHECTRL_CACHECTRL_INVALIDATE_GO; +} + +//***************************************************************************** +// +//! @brief Reset cache statistics. +//! +//! This function is used to reset cache statistics. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_cachectrl_reset_statistics(void) +{ + // + // Write the bit to reset flash statistics. + // Note - this bit is not sticky, no need to write it back to 0. + // + AM_REG(CACHECTRL, CACHECTRL) |= AM_REG_CACHECTRL_CACHECTRL_RESET_STAT_CLEAR; +} + +//***************************************************************************** +// +//! @brief Get flash cache sleep mode status. +//! +//! This function returns flash cache sleep mode statuses. +//! +//! @return +//! bit0 indicates that flash0 flash sleep mode is enabled. +//! bit1 indicates that flash1 flash sleep mode is enabled. +// +//***************************************************************************** +uint32_t +am_hal_cachectrl_sleep_mode_status(void) +{ + uint32_t ui32Status, ui32Ret; + + // + // Get the current sleep mode status bits. + // + ui32Status = AM_REG(CACHECTRL, CACHECTRL); + ui32Ret = (ui32Status & \ + AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_STATUS_M) >> \ + (AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_STATUS_S - 0); + ui32Ret |= (ui32Status & \ + AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_STATUS_M) >> \ + (AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_STATUS_S - 1); + + return ui32Ret; +} + +//***************************************************************************** +// +//! @brief Enable or disable flash cache sleep mode. +//! +//! This function enables or disables flash cache sleep mode. +//! @param ui32EnableMask - bit0 for flash0, bit1 for flash1. +//! @param ui32DisableMask - bit0 for flash0, bit1 for flash1. +//! +//! Note that if both an enable and disable are provided in their respective +//! masks, the enable will take precedence. +//! +//! @return Previous status. +//! bit0 indicates that flash0 flash sleep mode was previously enabled. +//! bit1 indicates that flash1 flash sleep mode was previously enabled. +// +//***************************************************************************** +uint32_t +am_hal_cachectrl_sleep_mode_enable(uint32_t ui32EnableMask, + uint32_t ui32DisableMask) +{ + uint32_t ui32Ret = am_hal_cachectrl_sleep_mode_status(); + + if ( ui32DisableMask & 0x1 ) + { + AM_REG(CACHECTRL, CACHECTRL) |= AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_DISABLE_M; + } + + if ( ui32DisableMask & 0x2 ) + { + AM_REG(CACHECTRL, CACHECTRL) |= AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_DISABLE_M; + } + + if ( ui32EnableMask & 0x1 ) + { + AM_REG(CACHECTRL, CACHECTRL) |= AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_ENABLE_M; + } + + if ( ui32EnableMask & 0x2 ) + { + AM_REG(CACHECTRL, CACHECTRL) |= AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_ENABLE_M; + } + + return ui32Ret; +} + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_cachectrl.h b/bsp/apollo2/libraries/drivers/hal/am_hal_cachectrl.h new file mode 100644 index 0000000000..b8ce914b94 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_cachectrl.h @@ -0,0 +1,211 @@ +//***************************************************************************** +// +// am_hal_cachectrl.h +//! @file +//! +//! @brief Functions for accessing and configuring the CACHE controller. +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_CACHECTRL_H +#define AM_HAL_CACHECTRL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Cache configuration structure +// +//***************************************************************************** +typedef struct +{ + // + //! Set to 1 to enable the cache. + // + uint8_t ui32EnableCache; + + // + //! Set to 1 to enable the LRU cache replacement policy. + //! Set to 0 to enable the LRR (least recently used) replacement policy. + //! LEE minimizes writes to the TAG SRAM. + // + uint8_t ui32LRU; + + // + //! Set to 3 to enable non-cachable region 1 and non-cachable region 0. + //! Set to 2 to enable non-cachable region 1. + //! Set to 1 to enable non-cachable region 0. + //! Set to 0 to make all regions cacheable. + // + uint8_t ui32EnableNCregions; + + // + //! Set to: + //! AM_HAL_CACHECTRL_CACHECFG_CONFIG_DIRECT_256 for direct-mapped, + //! 128-bit linesize, 256 entries (2 SRAMs active) + //! AM_HAL_CACHECTRL_CACHECFG_CONFIG_2WAY_256 for two-way set associative, + //! 128-bit linesize, 256 entries (4 SRAMs active) + //! AM_HAL_CACHECTRL_CACHECFG_CONFIG_2WAY_512 for two-way set associative, + //! 128-bit linesize, 512 entries (8 SRAMs active) + // + uint8_t ui32Config; + + // + //! Set to 1 to enable serial cache mode. + // + uint8_t ui32SerialCacheMode; + + // + //! Set to 3 to enable flash data caching and flash instruction caching. + //! Set to 2 to enable flash data caching. + //! Set to 1 to enable flash instruction caching. + //! Set to 0 to disable flash data caching and flash instruction caching. + // + uint8_t ui32FlashCachingEnables; + + // + //! Set to 1 to enable clock gating of cache RAMs. + // + uint8_t ui32EnableCacheClockGating; + + // + //! Set to 1 to enable light sleep of cache RAMs. + // + uint8_t ui32EnableLightSleep; + + // + //! Set Data RAM delay value (0x0 - 0xF). + // + uint8_t ui32Dly; + + // + //! Set SM Data RAM delay value (0x0 - 0xF). + // + uint8_t ui32SMDly; + + // + //! Set to 1 to enable clock gating of the entire data array. + // + uint8_t ui32EnableDataClockGating; + + // + //! Set to 1 to enable cache monitor statistics. + // + uint8_t ui32EnableCacheMonitoring; +} +am_hal_cachectrl_config_t; + +extern const am_hal_cachectrl_config_t am_hal_cachectrl_defaults; + +//***************************************************************************** +// +//! @name Cache enables +//! @brief Configuration selection for the various cache enables. +//! +//! These macros may be used in conjunction with the +//! am_hal_cachectrl_cache_enable() function to enable various cache features. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_CACHECTRL_CACHECFG_ENABLE AM_REG_CACHECTRL_CACHECFG_ENABLE_M +#define AM_HAL_CACHECTRL_CACHECFG_LRU_ENABLE AM_REG_CACHECTRL_CACHECFG_LRU_M +#define AM_HAL_CACHECTRL_CACHECFG_NC0_ENABLE AM_REG_CACHECTRL_CACHECFG_ENABLE_NC0_M +#define AM_HAL_CACHECTRL_CACHECFG_NC1_ENABLE AM_REG_CACHECTRL_CACHECFG_ENABLE_NC1_M +#define AM_HAL_CACHECTRL_CACHECFG_SERIAL_ENABLE AM_REG_CACHECTRL_CACHECFG_SERIAL_M +#define AM_HAL_CACHECTRL_CACHECFG_ICACHE_ENABLE AM_REG_CACHECTRL_CACHECFG_ICACHE_ENABLE_M +#define AM_HAL_CACHECTRL_CACHECFG_DCACHE_ENABLE AM_REG_CACHECTRL_CACHECFG_DCACHE_ENABLE_M +#define AM_HAL_CACHECTRL_CACHECFG_CACHE_CLKGATE_ENABLE AM_REG_CACHECTRL_CACHECFG_CACHE_CLKGATE_M +#define AM_HAL_CACHECTRL_CACHECFG_LS_ENABLE AM_REG_CACHECTRL_CACHECFG_CACHE_LS_M +#define AM_HAL_CACHECTRL_CACHECFG_DATA_CLKGATE_ENABLE AM_REG_CACHECTRL_CACHECFG_DATA_CLKGATE_M +#define AM_HAL_CACHECTRL_CACHECFG_MONITOR_ENABLE AM_REG_CACHECTRL_CACHECFG_ENABLE_MONITOR_M +//! @} + +//***************************************************************************** +// +//! @name Cache Config +//! @brief Configuration selection for the cache. +//! +//! These macros may be used in conjunction with the +//! am_hal_cachectrl_cache_config() function to select the cache type. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_CACHECTRL_CACHECFG_CONFIG_DIRECT_256 AM_REG_CACHECTRL_CACHECFG_CONFIG_W1_128B_256E +#define AM_HAL_CACHECTRL_CACHECFG_CONFIG_2WAY_256 AM_REG_CACHECTRL_CACHECFG_CONFIG_W2_128B_256E +#define AM_HAL_CACHECTRL_CACHECFG_CONFIG_2WAY_512 AM_REG_CACHECTRL_CACHECFG_CONFIG_W2_128B_512E +//! @} + +//***************************************************************************** +// +// Default cache settings +// +//***************************************************************************** +#define AM_HAL_CACHECTRL_DEFAULTS \ + (AM_HAL_CACHECTRL_CACHECFG_ICACHE_ENABLE | \ + AM_HAL_CACHECTRL_CACHECFG_DCACHE_ENABLE | \ + AM_HAL_CACHECTRL_CACHECFG_CACHE_CLKGATE_ENABLE | \ + AM_HAL_CACHECTRL_CACHECFG_DATA_CLKGATE_ENABLE | \ + AM_HAL_CACHECTRL_CACHECFG_CONFIG_2WAY_512) + +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern void am_hal_cachectrl_enable(const am_hal_cachectrl_config_t *psConfig); +extern void am_hal_cachectrl_disable(void); +extern void am_hal_cachectrl_config_default(void); +extern void am_hal_cachectrl_config(am_hal_cachectrl_config_t *psConfig); +extern uint32_t am_hal_cachectrl_cache_enables(uint32_t u32EnableMask, + uint32_t u32DisableMask); +extern void am_hal_cachectrl_cache_config(uint32_t ui32CacheConfig); +extern void am_hal_cachectrl_invalidate_flash_cache(void); +extern void am_hal_cachectrl_reset_statistics(void); +extern uint32_t am_hal_cachectrl_sleep_mode_status(void); +extern uint32_t am_hal_cachectrl_sleep_mode_enable(uint32_t ui32EnableMask, + uint32_t ui32DisableMask); + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_CACHECTRL_H diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_clkgen.c b/bsp/apollo2/libraries/drivers/hal/am_hal_clkgen.c new file mode 100644 index 0000000000..d60d7e47b5 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_clkgen.c @@ -0,0 +1,491 @@ +//***************************************************************************** +// +// am_hal_clkgen.c +//! @file +//! +//! @brief Functions for interfacing with the CLKGEN. +//! +//! @addtogroup clkgen2 Clock Generator (CLKGEN) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +// CLKGEN HFADJ register +// +//***************************************************************************** +#define AM_REG_CLKGEN_HFADJ_HFXTADJ_DEFAULT 0x5B8 + +//***************************************************************************** +// +//! @brief Select the clock divisor for the main system clock. +//! +//! @param ui32ClockSetting - The divisor value for the system clock. +//! +//! This function can be used to select the frequency of the main system clock. +//! The \e ui32ClockSetting parameter should be set to one of the following +//! values: +//! +//! AM_HAL_CLKGEN_SYSCLK_MAX +//! AM_HAL_CLKGEN_SYSCLK_48MHZ +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_clkgen_sysclk_select(uint32_t ui32ClockSetting) +{ + am_hal_debug_assert_msg(ui32ClockSetting == AM_HAL_CLKGEN_SYSCLK_48MHZ, + "am_hal_clkgen_sysclk_select(): invalid clock setting."); + + // + // Unlock the clock control register. + // + AM_REG(CLKGEN, CLKKEY) = AM_REG_CLKGEN_CLKKEY_KEYVAL; + + // + // Set the HFRC divisor to the user-selected value. + // + AM_REG(CLKGEN, CCTRL) = ui32ClockSetting; + + // + // Lock the clock configuration registers. + // + AM_REG(CLKGEN, CLKKEY) = 0; +} + +//***************************************************************************** +// +//! @brief Get the current system clock frequency. +//! +//! This function can be used to determine the frequency of the main system +//! clock. The return value is the system clock frequency measured in hertz. +//! +//! @return System clock frequency in Hz +// +//***************************************************************************** +uint32_t +am_hal_clkgen_sysclk_get(void) +{ + uint32_t ui32ClockSetting; + + // + // Read the value of the clock divider. + // + ui32ClockSetting = AM_REG(CLKGEN, CCTRL) & AM_REG_CLKGEN_CCTRL_CORESEL_M; + + switch ( ui32ClockSetting ) + { + case AM_REG_CLKGEN_CCTRL_CORESEL_HFRC: + return 48000000; + case AM_REG_CLKGEN_CCTRL_CORESEL_HFRC_DIV2: + return 24000000; + default: + return 0xFFFFFFFF; + } +} + +//***************************************************************************** +// +//! @brief Enable selected CLKGEN Interrupts. +//! +//! Use this function to enable the interrupts. +//! +//! @param ui32Interrupt - Use the macro bit fields provided in am_hal_clkgen.h +//! +//! @return None +// +//***************************************************************************** +void +am_hal_clkgen_int_enable(uint32_t ui32Interrupt) +{ + // + // Enable the interrupts. + // + AM_REG(CLKGEN, INTEN) |= ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Return enabled CLKGEN Interrupts. +//! +//! Use this function to get all enabled CLKGEN interrupts. +//! +//! @return enabled CLKGEN interrupts. +// +//***************************************************************************** +uint32_t +am_hal_clkgen_int_enable_get(void) +{ + // + // Return the enabled interrupts. + // + return AM_REG(CLKGEN, INTEN); +} + +//***************************************************************************** +// +//! @brief Disable selected CLKGEN Interrupts. +//! +//! Use this function to disable the CLKGEN interrupts. +//! +//! @param ui32Interrupt - Use the macro bit fields provided in am_hal_clkgen.h +//! +//! @return None +// +//***************************************************************************** +void +am_hal_clkgen_int_disable(uint32_t ui32Interrupt) +{ + // + // Disable the interrupts. + // + AM_REG(CLKGEN, INTEN) &= ~ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Sets the interrupt status. +//! +//! @param ui32IntFlags interrupts to be enabled. +//! +//! This function sets the interrupts. +//! +//! Valid values for ui32IntFlags are: +//! +//! AM_HAL_CLKGEN_INT_RTC_ALARM +//! AM_HAL_CLKGEN_INT_XT_FAIL +//! AM_HAL_CLKGEN_INT_AUTOCAL_COMPLETE +//! AM_HAL_CLKGEN_INT AUTOCAL_FAIL +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_clkgen_int_set(uint32_t ui32Interrupt) +{ + // + // Set the interrupt status. + // + AM_REG(CLKGEN, INTSET) = ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Gets the interrupt configuration. +//! +//! @param bEnabledOnly - return the status of only the enabled interrupts. +//! +//! This function gets the currently configured interrupts. +//! +//! @return the configured interrupts. +//! +//! Possible values for the return are: +//! +//! AM_HAL_CLKGEN_INT_RTC_ALARM +//! AM_HAL_CLKGEN_INT_XT_FAIL +//! AM_HAL_CLKGEN_INT_AUTOCAL_COMPLETE +//! AM_HAL_CLKGEN_INT AUTOCAL_FAIL +// +//***************************************************************************** +uint32_t +am_hal_clkgen_int_status_get(bool bEnabledOnly) +{ + // + // Return the status. + // + if ( bEnabledOnly ) + { + uint32_t u32RetVal = AM_REG(CLKGEN, INTSTAT); + u32RetVal &= AM_REG(CLKGEN, INTEN); + return u32RetVal; + } + else + { + return AM_REG(CLKGEN, INTSTAT); + } +} + +//***************************************************************************** +// +//! @brief Clears the interrupts. +//! +//! @param ui32IntFlags interrupts to be cleared. +//! +//! This function clears the interrupts. +//! +//! Valid values for ui32IntFlags are: +//! +//! AM_HAL_CLKGEN_INT_RTC_ALARM +//! AM_HAL_CLKGEN_INT_XT_FAIL +//! AM_HAL_CLKGEN_INT_AUTOCAL_COMPLETE +//! AM_HAL_CLKGEN_INT AUTOCAL_FAIL +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_clkgen_int_clear(uint32_t ui32Interrupt) +{ + // + // Clear the interrupts. + // + AM_REG(CLKGEN, INTCLR) = ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Starts the desired oscillator(s) (OSC). +//! +//! @param ui32OscFlags oscillator(s) to start. +//! +//! This function starts the desired oscillator(s) (OSC). +//! +//! Valid values for ui32OscFlags are: +//! +//! AM_HAL_CLKGEN_OSC_LFRC +//! AM_HAL_CLKGEN_OSC_XT +//! +//! @return 0 None. +// +//***************************************************************************** +void +am_hal_clkgen_osc_start(uint32_t ui32OscFlags) +{ + // + // Start the oscillator(s). + // + AM_REG(CLKGEN, OCTRL) &= ~ui32OscFlags; +} + +//***************************************************************************** +// +//! @brief Stops the desired oscillator(s) (OSC). +//! +//! @param ui32OscFlags oscillator(s) to stop. +//! +//! This function stops the desired oscillator(s) (OSC). +//! +//! Valid values for ui32OscFlags are: +//! +//! AM_HAL_CLKGEN_OSC_LFRC +//! AM_HAL_CLKGEN_OSC_XT +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_clkgen_osc_stop(uint32_t ui32OscFlags) +{ + // + // Stop the oscillator(s). + // + AM_REG(CLKGEN, OCTRL) |= ui32OscFlags; +} + +//***************************************************************************** +// +//! @brief Enables the clock out signal. +//! +//! @param ui32Signal desired location for the clock out signal. +//! +//! This function enables the clock out signal. See am_hal_clkgen.h for +//! available signals. +//! +//! e.g. AM_HAL_CLKGEN_CLKOUT_CKSEL_HFRC +//! AM_HAL_CLKGEN_CLKOUT_CKSEL_HFRC_DIV4 +//! AM_HAL_CLKGEN_CLKOUT_CKSEL_LFRC +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_clkgen_clkout_enable(uint32_t ui32Signal) +{ + // + // Enable the clock out on desired signal. + // + AM_REG(CLKGEN, CLKOUT) = AM_REG_CLKGEN_CLKOUT_CKEN_M | ui32Signal; +} + +//***************************************************************************** +// +//! @brief Disables the clock out signal. +//! +//! This function disables the clock out signal. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_clkgen_clkout_disable(void) +{ + // + // Disable the clock out. + // + AM_REG(CLKGEN, CLKOUT) = 0; +} + +//***************************************************************************** +// +//! @brief Enable UART system clock. +//! +//! This function enables or disables the UART system clock. +//! +//! @param ui32Module is 0 or 1 for Apollo2. +//! @param ui32UartEn is one of the following. +//! AM_HAL_CLKGEN_UARTEN_DIS +//! AM_HAL_CLKGEN_UARTEN_EN +//! AM_HAL_CLKGEN_UARTEN_REDUCE_FREQ +//! AM_HAL_CLKGEN_UARTEN_EN_POWER_SAV +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_clkgen_uarten_set(uint32_t ui32Module, uint32_t ui32UartEn) +{ + uint32_t ui32Mask; + + if ( (ui32Module >= AM_REG_UART_NUM_MODULES) || + (ui32UartEn > AM_HAL_CLKGEN_UARTEN_EN_POWER_SAV) ) + { + return; + } + + ui32UartEn <<= (ui32Module * AM_HAL_CLKGEN_UARTEN_UARTENn_S(ui32Module)); + ui32Mask = ~(AM_HAL_CLKGEN_UARTEN_UARTENn_M(ui32Module)); + + // + // Begin critical section. + // + AM_CRITICAL_BEGIN_ASM + + // + // Set the UART clock + // + AM_REG(CLKGEN, UARTEN) &= ui32Mask; + AM_REG(CLKGEN, UARTEN) |= ui32UartEn; + + // + // Begin critical section. + // + AM_CRITICAL_END_ASM +} + +//***************************************************************************** +// +//! @brief Enables HFRC auto-adjustment at the specified interval. +//! +//! @param ui32Warmup - How long to give the HFRC to stabilize during each +//! calibration attempt. +//! @param ui32Frequency - How often the auto-adjustment should happen. +//! +//! This function enables HFRC auto-adjustment from an external crystal +//! oscillator even when the crystal is not normally being used. +//! +//! ui32Warmup should be one of the following values: +//! +//! AM_REG_CLKGEN_HFADJ_HFWARMUP_1SEC +//! AM_REG_CLKGEN_HFADJ_HFWARMUP_2SEC +//! +//! ui32Frequency should be one of the following values: +//! +//! AM_REG_CLKGEN_HFADJ_HFADJCK_4SEC +//! AM_REG_CLKGEN_HFADJ_HFADJCK_16SEC +//! AM_REG_CLKGEN_HFADJ_HFADJCK_32SEC +//! AM_REG_CLKGEN_HFADJ_HFADJCK_64SEC +//! AM_REG_CLKGEN_HFADJ_HFADJCK_128SEC +//! AM_REG_CLKGEN_HFADJ_HFADJCK_256SEC +//! AM_REG_CLKGEN_HFADJ_HFADJCK_512SEC +//! AM_REG_CLKGEN_HFADJ_HFADJCK_1024SEC +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_clkgen_hfrc_adjust_enable(uint32_t ui32Warmup, uint32_t ui32Frequency) +{ + // + // Set the HFRC Auto-adjust register for the user's chosen settings. Assume + // that the HFRC should be calibrated to 48 MHz and that the crystal is + // running at 32.768 kHz. + // + AM_REG(CLKGEN, HFADJ) = + AM_REG_CLKGEN_HFADJ_HFADJ_GAIN_Gain_of_1_in_2 | + ui32Warmup | + AM_REG_CLKGEN_HFADJ_HFXTADJ(AM_REG_CLKGEN_HFADJ_HFXTADJ_DEFAULT) | + ui32Frequency | + AM_REG_CLKGEN_HFADJ_HFADJEN_EN; +} + +//***************************************************************************** +// +//! @brief Disables HFRC auto-adjustment. +//! +//! This function disables HFRC auto-adjustment. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_clkgen_hfrc_adjust_disable(void) +{ + // + // Disable the clock out. + // + AM_REG(CLKGEN, HFADJ) = + AM_REG_CLKGEN_HFADJ_HFADJ_GAIN_Gain_of_1_in_2 | + AM_REG_CLKGEN_HFADJ_HFWARMUP_1SEC | + AM_REG_CLKGEN_HFADJ_HFXTADJ(AM_REG_CLKGEN_HFADJ_HFXTADJ_DEFAULT) | + AM_REG_CLKGEN_HFADJ_HFADJCK_4SEC | + AM_REG_CLKGEN_HFADJ_HFADJEN_DIS; +} + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_clkgen.h b/bsp/apollo2/libraries/drivers/hal/am_hal_clkgen.h new file mode 100644 index 0000000000..fc50cb9b43 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_clkgen.h @@ -0,0 +1,206 @@ +//***************************************************************************** +// +// am_hal_clkgen.h +//! @file +//! +//! @brief Functions for accessing and configuring the CLKGEN. +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_CLKGEN_H +#define AM_HAL_CLKGEN_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +//! @name System Clock max frequency +//! @brief Defines the maximum clock frequency for this device. +//! +//! These macros provide a definition of the maximum clock frequency. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_CLKGEN_FREQ_MAX_HZ 48000000 +#define AM_HAL_CLKGEN_FREQ_MAX_MHZ (AM_HAL_CLKGEN_FREQ_MAX_HZ / 1000000) +//! @} + +//***************************************************************************** +// +//! @name System Clock Selection +//! @brief Divisor selection for the main system clock. +//! +//! These macros may be used along with the am_hal_clkgen_sysctl_select() +//! function to select the frequency of the main system clock. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_CLKGEN_SYSCLK_MAX AM_REG_CLKGEN_CCTRL_CORESEL_HFRC +#define AM_HAL_CLKGEN_SYSCLK_48MHZ AM_REG_CLKGEN_CCTRL_CORESEL_HFRC +//! @} + +//***************************************************************************** +// +//! @name Interrupt Status Bits +//! @brief Interrupt Status Bits for enable/disble use +//! +//! These macros may be used to set and clear interrupt bits. +//! @{ +// +//***************************************************************************** +#define AM_HAL_CLKGEN_INT_ALM AM_REG_CLKGEN_INTEN_ALM_M +#define AM_HAL_CLKGEN_INT_OF AM_REG_CLKGEN_INTEN_OF_M +#define AM_HAL_CLKGEN_INT_ACC AM_REG_CLKGEN_INTEN_ACC_M +#define AM_HAL_CLKGEN_INT_ACF AM_REG_CLKGEN_INTEN_ACF_M +//! @} + +//***************************************************************************** +// +//! @name OSC Start and Stop +//! @brief OSC Start and Stop defines. +//! +//! OSC Start and Stop defines to be used with \e am_hal_clkgen_osc_x(). +//! @{ +// +//***************************************************************************** +#define AM_HAL_CLKGEN_OSC_LFRC AM_REG_CLKGEN_OCTRL_STOPRC_M +#define AM_HAL_CLKGEN_OSC_XT AM_REG_CLKGEN_OCTRL_STOPXT_M +//! @} + +//***************************************************************************** +// +// OSC Start, Stop, Select defines +// +//***************************************************************************** +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_LFRC AM_REG_CLKGEN_CLKOUT_CKSEL_LFRC +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_XT_DIV2 AM_REG_CLKGEN_CLKOUT_CKSEL_XT_DIV2 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_XT_DIV4 AM_REG_CLKGEN_CLKOUT_CKSEL_XT_DIV4 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_XT_DIV8 AM_REG_CLKGEN_CLKOUT_CKSEL_XT_DIV8 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_XT_DIV16 AM_REG_CLKGEN_CLKOUT_CKSEL_XT_DIV16 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_XT_DIV32 AM_REG_CLKGEN_CLKOUT_CKSEL_XT_DIV32 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_RTC_100Hz AM_REG_CLKGEN_CLKOUT_CKSEL_RTC_100Hz +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_XT_DIV2M AM_REG_CLKGEN_CLKOUT_CKSEL_XT_DIV2M +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_XT AM_REG_CLKGEN_CLKOUT_CKSEL_XT +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_CG_100Hz AM_REG_CLKGEN_CLKOUT_CKSEL_CG_100Hz +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_HFRC AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_HFRC_DIV4 AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC_DIV4 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_HFRC_DIV8 AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC_DIV8 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_HFRC_DIV32 AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC_DIV32 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_HFRC_DIV64 AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC_DIV64 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_HFRC_DIV128 AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC_DIV128 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_HFRC_DIV256 AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC_DIV256 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_CORE_CLK AM_REG_CLKGEN_CLKOUT_CKSEL_CORE_CLK +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_FLASH_CLK AM_REG_CLKGEN_CLKOUT_CKSEL_FLASH_CLK +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_LFRC_DIV2 AM_REG_CLKGEN_CLKOUT_CKSEL_LFRC_DIV2 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_LFRC_DIV32 AM_REG_CLKGEN_CLKOUT_CKSEL_LFRC_DIV32 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_LFRC_DIV512 AM_REG_CLKGEN_CLKOUT_CKSEL_LFRC_DIV512 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_LFRC_DIV32K AM_REG_CLKGEN_CLKOUT_CKSEL_LFRC_DIV32K +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_XT_DIV256 AM_REG_CLKGEN_CLKOUT_CKSEL_XT_DIV256 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_XT_DIV8K AM_REG_CLKGEN_CLKOUT_CKSEL_XT_DIV8K +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_XT_DIV64K AM_REG_CLKGEN_CLKOUT_CKSEL_XT_DIV64K +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_ULFRC_DIV16 AM_REG_CLKGEN_CLKOUT_CKSEL_ULFRC_DIV16 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_ULFRC_DIV128 AM_REG_CLKGEN_CLKOUT_CKSEL_ULFRC_DIV128 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_ULFRC_1Hz AM_REG_CLKGEN_CLKOUT_CKSEL_ULFRC_1Hz +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_ULFRC_DIV4K AM_REG_CLKGEN_CLKOUT_CKSEL_ULFRC_DIV4K +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_ULFRC_DIV1M AM_REG_CLKGEN_CLKOUT_CKSEL_ULFRC_DIV1M +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_HFRC_DIV64K AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC_DIV64K +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_HFRC_DIV16M AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC_DIV16M +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_LFRC_DIV2M AM_REG_CLKGEN_CLKOUT_CKSEL_LFRC_DIV2M +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_HFRCNE AM_REG_CLKGEN_CLKOUT_CKSEL_HFRCNE +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_HFRCNE_DIV8 AM_REG_CLKGEN_CLKOUT_CKSEL_HFRCNE_DIV8 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_CORE_CLKNE AM_REG_CLKGEN_CLKOUT_CKSEL_CORE_CLKNE +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_XTNE AM_REG_CLKGEN_CLKOUT_CKSEL_XTNE +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_XTNE_DIV16 AM_REG_CLKGEN_CLKOUT_CKSEL_XTNE_DIV16 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_LFRCNE_DIV32 AM_REG_CLKGEN_CLKOUT_CKSEL_LFRCNE_DIV32 +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_FCLKNE AM_REG_CLKGEN_CLKOUT_CKSEL_FCLKNE +#define AM_HAL_CLKGEN_CLKOUT_CKSEL_LFRCNE AM_REG_CLKGEN_CLKOUT_CKSEL_LFRCNE + +//***************************************************************************** +// +// UARTEN +// +//***************************************************************************** +#define AM_HAL_CLKGEN_UARTEN_DIS AM_REG_CLKGEN_UARTEN_UART0EN_DIS +#define AM_HAL_CLKGEN_UARTEN_EN AM_REG_CLKGEN_UARTEN_UART0EN_EN +#define AM_HAL_CLKGEN_UARTEN_REDUCE_FREQ AM_REG_CLKGEN_UARTEN_UART0EN_REDUCE_FREQ +#define AM_HAL_CLKGEN_UARTEN_EN_POWER_SAV AM_REG_CLKGEN_UARTEN_UART0EN_EN_POWER_SAV + +#define AM_HAL_CLKGEN_UARTEN_UARTENn_S(module) \ + ((module) * \ + (AM_REG_CLKGEN_UARTEN_UART1EN_S - AM_REG_CLKGEN_UARTEN_UART0EN_S)) + +#define AM_HAL_CLKGEN_UARTEN_UARTENn_M(module) \ + (AM_REG_CLKGEN_UARTEN_UART0EN_M << AM_HAL_CLKGEN_UARTEN_UARTENn_S(module)) + +// +// UARTEN: entype is one of DIS, EN, REDUCE_FREQ, EN_POWER_SAV. +// +#define AM_HAL_CLKGEN_UARTEN_UARTENn(module, entype) \ + (AM_REG_CLKGEN_UARTEN_UART0EN_##entype << \ + AM_HAL_CLKGEN_UARTEN_UARTENn_S(module)) + +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern void am_hal_clkgen_sysclk_select(uint32_t ui32ClockSetting); +extern uint32_t am_hal_clkgen_sysclk_get(void); +extern void am_hal_clkgen_osc_start(uint32_t ui32OscFlags); +extern void am_hal_clkgen_osc_stop(uint32_t ui32OscFlags); +extern void am_hal_clkgen_clkout_enable(uint32_t ui32Signal); +extern void am_hal_clkgen_clkout_disable(void); +extern void am_hal_clkgen_uarten_set(uint32_t ui32Module, uint32_t ui32UartEn); +extern void am_hal_clkgen_int_enable(uint32_t ui32Interrupt); +extern uint32_t am_hal_clkgen_int_enable_get(void); +extern void am_hal_clkgen_int_disable(uint32_t ui32Interrupt); +extern void am_hal_clkgen_int_clear(uint32_t ui32Interrupt); +extern void am_hal_clkgen_int_set(uint32_t ui32Interrupt); +extern uint32_t am_hal_clkgen_int_status_get(bool bEnabledOnly); +extern void am_hal_clkgen_hfrc_adjust_enable(uint32_t ui32Warmup, uint32_t ui32Frequency); +extern void am_hal_clkgen_hfrc_adjust_disable(void); + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_CLKGEN_H diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_ctimer.c b/bsp/apollo2/libraries/drivers/hal/am_hal_ctimer.c new file mode 100644 index 0000000000..13fc3c07cc --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_ctimer.c @@ -0,0 +1,1687 @@ +//***************************************************************************** +// +// am_hal_ctimer.c +//! @file +//! +//! @brief Functions for interfacing with the Counter/Timer module. +//! +//! @addtogroup ctimer2 Counter/Timer (CTIMER) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +// Address space distance between timer configuration registers. +// +//***************************************************************************** +#define MAX_CTIMERS 4 +#define TIMER_OFFSET (AM_REG_CTIMER_TMR1_O - AM_REG_CTIMER_TMR0_O) +#define CTIMER_CMPR_OFFSET (AM_REG_CTIMER_CMPRB0_O - AM_REG_CTIMER_CMPRA0_O) + +//***************************************************************************** +// +// Adjacency check +// +// This is related to the timer read workaround. This macro checks to see if +// the two supplied count values are within one "tick" of eachother. It should +// still pass in the event of a timer rollover. +// +//***************************************************************************** +#define adjacent(A, B) (((A) == (B)) || (((A) + 1) == (B)) || ((B) == 0)) + +//***************************************************************************** +// +// Array of function pointers for handling CTimer interrupts. +// +//***************************************************************************** +am_hal_ctimer_handler_t am_hal_ctimer_ppfnHandlers[16]; + +//***************************************************************************** +// +// Static function for reading the timer value. +// +//***************************************************************************** +#if defined(__GNUC_STDC_INLINE__) +__attribute__((naked)) +static +void +back2back_reads(uint32_t u32TimerAddr, uint32_t u32Data[]) +{ + // u32TimerAddr = address of the timer to be read. + // u32Data[] is a pointer to a 3 word data array provided by the caller. + __asm + ( + // Do 3 back-to-back reads of the register + " push {r4}\n" // Save r4 + " push {r1}\n" // Save the data array ptr for later + " mov r2, r0\n" // Get Timer Addr + " mrs r4, PRIMASK\n" // Save PRIMASK + " cpsid i\n" // __disable_irq() + " nop\n" // Give the disable a cycle to take affect (but almost certainly not really needed) + " ldr r0, [r2, #0]\n" // Get TMRn register value + " ldr r1, [r2, #0]\n" // Get TMRn register value again + " ldr r3, [r2, #0]\n" // Get TMRn register value for a third time + " msr PRIMASK, r4\n" // Restore PRIMASK + " pop {r2}\n" // Get the array ptr + " str r0, [r2, #0]\n" // Store register value to variable + " str r1, [r2, #4]\n" // Store register value to variable + " str r3, [r2, #8]\n" // Store register value to variable + " pop {r4}\n" // restore r4 + " bx lr\n" + ); +} + +#elif defined(__ARMCC_VERSION) +__asm static uint32_t +back2back_reads( uint32_t u32TimerAddr, uint32_t u32Data[]) +{ + push {r4} // Save r4 + push {r1} // Save the data array ptr for later + mov r2, r0 // Get Timer Addr + mrs r4, PRIMASK // Save PRIMASK + cpsid i // __disable_irq() + nop // Give the disable a cycle to take affect (but almost certainly not really needed) + ldr r0, [r2, #0] // Get TMRn register value + ldr r1, [r2, #0] // Get TMRn register value again + ldr r3, [r2, #0] // Get TMRn register value for a third time + msr PRIMASK, r4 // Restore PRIMASK + pop {r2} // Get the array ptr + str r0, [r2, #0] // Store register value to variable + str r1, [r2, #4] // Store register value to variable + str r3, [r2, #8] // Store register value to variable + pop {r4} // Restore r4 + bx lr +} + +#elif defined(__IAR_SYSTEMS_ICC__) +#pragma diag_suppress = Pe940 // Suppress IAR compiler warning about missing + // return statement on a non-void function +__stackless static uint32_t +back2back_reads( uint32_t u32TimerAddr, uint32_t u32Data[]) +{ + __asm(" push {r4}"); // Save r4 + __asm(" push {r1}"); // Save the data array ptr for later + __asm(" mov r2, r0"); // Get Timer Addr + __asm(" mrs r4, PRIMASK"); // Save PRIMASK" + __asm(" cpsid i"); // __disable_irq() + __asm(" nop"); // Give the disable a cycle to take affect (but almost certainly not really needed) + __asm(" ldr r0, [r2, #0]"); // Get TMRn register value + __asm(" ldr r1, [r2, #0]"); // Get TMRn register value again + __asm(" ldr r3, [r2, #0]"); // Get TMRn register value for a third time + __asm(" msr PRIMASK, r4"); // Restore PRIMASK + __asm(" pop {r2}"); // Get the array ptr + __asm(" str r0, [r2, #0]"); // Store register value to variable + __asm(" str r1, [r2, #4]"); // Store register value to variable + __asm(" str r3, [r2, #8]"); // Store register value to variable + __asm(" pop {r4}"); // Restore r4 + __asm(" bx lr"); +} +#pragma diag_default = Pe940 // Restore IAR compiler warning +#endif + +//***************************************************************************** +// +// @brief Check to see if the given CTimer is using the HFRC +// +// Note - Calls to this function should be from inside a critical section. +// +//! @return None. +// +//***************************************************************************** +static bool +ctimer_source_hfrc(uint32_t ui32CtimerNum) +{ + uint32_t *pui32ConfigReg; + uint32_t ui32TimerASrc, ui32TimerBSrc; + + // + // Find the correct register to write. + // + pui32ConfigReg = (uint32_t *)(AM_REG_CTIMERn(0) + AM_REG_CTIMER_CTRL0_O + + (ui32CtimerNum * TIMER_OFFSET)); + + // + // Determine if this timer is using HFRC as the clock source. + // The value we are looking for is HFRC_DIV4 to HFRC_DIV4K. + // Get the clock sources and 0-base the extracted value. + // + ui32TimerASrc = AM_BFX(CTIMER, CTRL0, TMRA0CLK, *pui32ConfigReg) - + AM_ENUMX(CTIMER, CTRL0, TMRA0CLK, HFRC_DIV4); + ui32TimerBSrc = AM_BFX(CTIMER, CTRL0, TMRB0CLK, *pui32ConfigReg) - + AM_ENUMX(CTIMER, CTRL0, TMRB0CLK, HFRC_DIV4); + + // + // If the source value is 0 to (HFRC_DIV4K - HFRC_DIV4), then it's HFRC. + // + if ( (ui32TimerASrc <= (AM_ENUMX(CTIMER, CTRL0, TMRA0CLK, HFRC_DIV4K) - + AM_ENUMX(CTIMER, CTRL0, TMRA0CLK, HFRC_DIV4))) || + (ui32TimerBSrc <= (AM_ENUMX(CTIMER, CTRL0, TMRB0CLK, HFRC_DIV4K) - + AM_ENUMX(CTIMER, CTRL0, TMRB0CLK, HFRC_DIV4))) ) + { + return true; + } + else + { + return false; + } + +} // ctimer_source_hfrc() + +//***************************************************************************** +// +// @brief Check to see if any of the CTimers or STimer are using the HFRC. +// +// This function should be used to check if the HFRC is being used in order +// to correctly establish power related settings. +// +// Note - Calls to this function should be from inside a critical section. +// +//! @return None. +// +//***************************************************************************** +static bool +timers_use_hfrc(void) +{ + uint32_t ui32TimerASrc, ui32CtimerNum; + + // + // Check STimer to see if it is using HFRC. + // + ui32TimerASrc = AM_BFR(CTIMER, STCFG, CLKSEL); + if ( (ui32TimerASrc == AM_REG_CTIMER_STCFG_CLKSEL_HFRC_DIV16) || + (ui32TimerASrc == AM_REG_CTIMER_STCFG_CLKSEL_HFRC_DIV256) ) + { + return true; + } + + // + // Check the CTimers to see if any are using HFRC as their clock source. + // + for ( ui32CtimerNum = 0; ui32CtimerNum < MAX_CTIMERS; ui32CtimerNum++ ) + { + if ( ctimer_source_hfrc(ui32CtimerNum) ) + { + return true; + } + } + + return false; + +} // timers_use_hfrc() + +//***************************************************************************** +// +//! @brief Convenience function for responding to CTimer interrupts. +//! +//! @param ui32Status is the interrupt status as returned by +//! am_hal_ctimer_int_status_get() +//! +//! This function may be called from am_ctimer_isr() to read the status of +//! the CTimer interrupts, determine which source caused the most recent +//! interrupt, and call an interrupt handler function to respond. The interrupt +//! handler to be called must be first registered with the +//! am_hal_ctimer_int_register() function. +//! +//! In the event that multiple sources are active, the corresponding +//! interrupt handlers will be called in numerical order based on interrupt def. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ctimer_int_service(uint32_t ui32Status) +{ + uint32_t ui32Clz; + + am_hal_ctimer_handler_t pfnHandler; + + ui32Status &= 0xFFFF; + + while ( ui32Status ) + { + // + // Pick one of any remaining active interrupt bits + // +#ifdef __IAR_SYSTEMS_ICC__ + ui32Clz = __CLZ(ui32Status); +#else + ui32Clz = __builtin_clz(ui32Status); +#endif + + // + // Turn off the bit we picked in the working copy + // + ui32Status &= ~(0x80000000 >> ui32Clz); + + // + // Check the bit handler table to see if there is an interrupt handler + // registered for this particular bit. + // + pfnHandler = am_hal_ctimer_ppfnHandlers[31 - ui32Clz]; + if ( pfnHandler ) + { + // + // If we found an interrupt handler routine, call it now. + // + pfnHandler(); + } + } +} // am_hal_ctimer_int_service() + +//***************************************************************************** +// +//! @brief Register an interrupt handler for CTimer. +//! +//! @param ui32Interrupt - interrupt number to assign this interrupt handler to. +//! @param pfnHandler - Function to call when this interrupt is received. +//! +//! This function allows the caller to specify a function that should be called +//! any time a Ctimer interrupt is received. Registering an +//! interrupt handler using this function adds the function pointer to an array +//! in SRAM. This interrupt handler will be called by am_hal_ctimer_int_service() +//! whenever the ui32Status parameter indicates that the corresponding interrupt. +//! +//! To remove an interrupt handler that has already been registered, the +//! pfnHandler parameter may be set to zero. +//! +//! @note This function will not have any effect unless the +//! am_hal_ctimer_int_service() function is being used. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ctimer_int_register(uint32_t ui32Interrupt, + am_hal_ctimer_handler_t pfnHandler) +{ + uint32_t intIdx = 0; + + // + // Check to make sure the interrupt number is valid. (Debug builds only) + // + switch (ui32Interrupt) + { + case AM_REG_CTIMER_INTEN_CTMRA0C0INT_M: + intIdx = AM_REG_CTIMER_INTEN_CTMRA0C0INT_S; + break; + + case AM_REG_CTIMER_INTEN_CTMRB0C0INT_M: + intIdx = AM_REG_CTIMER_INTEN_CTMRB0C0INT_S; + break; + + case AM_REG_CTIMER_INTEN_CTMRA1C0INT_M: + intIdx = AM_REG_CTIMER_INTEN_CTMRA1C0INT_S; + break; + + case AM_REG_CTIMER_INTEN_CTMRB1C0INT_M: + intIdx = AM_REG_CTIMER_INTEN_CTMRB1C0INT_S; + break; + + case AM_REG_CTIMER_INTEN_CTMRA2C0INT_M: + intIdx = AM_REG_CTIMER_INTEN_CTMRA2C0INT_S; + break; + + case AM_REG_CTIMER_INTEN_CTMRB2C0INT_M: + intIdx = AM_REG_CTIMER_INTEN_CTMRB2C0INT_S; + break; + + case AM_REG_CTIMER_INTEN_CTMRA3C0INT_M: + intIdx = AM_REG_CTIMER_INTEN_CTMRA3C0INT_S; + break; + + case AM_REG_CTIMER_INTEN_CTMRB3C0INT_M: + intIdx = AM_REG_CTIMER_INTEN_CTMRB3C0INT_S; + break; + + case AM_REG_CTIMER_INTEN_CTMRA0C1INT_M: + intIdx = AM_REG_CTIMER_INTEN_CTMRA0C1INT_S; + break; + + case AM_REG_CTIMER_INTEN_CTMRB0C1INT_M: + intIdx = AM_REG_CTIMER_INTEN_CTMRB0C1INT_S; + break; + + case AM_REG_CTIMER_INTEN_CTMRA1C1INT_M: + intIdx = AM_REG_CTIMER_INTEN_CTMRA1C1INT_S; + break; + + case AM_REG_CTIMER_INTEN_CTMRB1C1INT_M: + intIdx = AM_REG_CTIMER_INTEN_CTMRB1C1INT_S; + break; + + case AM_REG_CTIMER_INTEN_CTMRA2C1INT_M: + intIdx = AM_REG_CTIMER_INTEN_CTMRA2C1INT_S; + break; + + case AM_REG_CTIMER_INTEN_CTMRB2C1INT_M: + intIdx = AM_REG_CTIMER_INTEN_CTMRB2C1INT_S; + break; + + case AM_REG_CTIMER_INTEN_CTMRA3C1INT_M: + intIdx = AM_REG_CTIMER_INTEN_CTMRA3C1INT_S; + break; + + case AM_REG_CTIMER_INTEN_CTMRB3C1INT_M: + intIdx = AM_REG_CTIMER_INTEN_CTMRB3C1INT_S; + break; + + default: + am_hal_debug_assert_msg(false, "CTimer interrupt number out of range."); + } + + am_hal_ctimer_ppfnHandlers[intIdx] = pfnHandler; + +} // am_hal_ctimer_int_register() + +//***************************************************************************** +// +//! @brief Set up the counter/timer. +//! +//! @param ui32TimerNumber is the number of the Timer that should be +//! configured. +//! +//! @param psConfig is a pointer to a structure that holds important settings +//! for the timer. +//! +//! This function should be used to perform the initial set-up of the +//! counter-timer. +//! +//! @note This function will eventually be replaced by +//! am_hal_ctimer_config_single(), which performs the same configuration +//! without requiring a structure. Please use am_hal_ctimer_config_single() for +//! new development. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ctimer_config(uint32_t ui32TimerNumber, + am_hal_ctimer_config_t *psConfig) +{ + uint32_t *pui32ConfigReg; + uint32_t ui32ConfigVal; + + // + // Start preparing the configuration word for this timer. The configuration + // values for Timer A and Timer B provided in the config structure should + // match the register definitions already, so we will mostly just need to + // OR them together. + // + ui32ConfigVal = ( (psConfig->ui32TimerAConfig) | + (psConfig->ui32TimerBConfig << 16) ); + + // + // OR in the Link bit if the timers need to be linked. + // + ui32ConfigVal |= psConfig->ui32Link ? AM_HAL_CTIMER_LINK : 0; + + // + // Begin critical section while config registers are read and modified. + // + AM_CRITICAL_BEGIN_ASM + + // + // Find the correct register to write. + // + pui32ConfigReg = (uint32_t *)(AM_REG_CTIMERn(0) + AM_REG_CTIMER_CTRL0_O + + (ui32TimerNumber * TIMER_OFFSET)); + + // + // Write our configuration value. + // + AM_REGVAL(pui32ConfigReg) = ui32ConfigVal; + + // + // If all of the clock sources are not HRFC disable LDO when sleeping if timers are enabled. + // + if ( timers_use_hfrc() ) + { + AM_BFW(PWRCTRL, MISCOPT, DIS_LDOLPMODE_TIMERS, 0); + } + else + { + AM_BFW(PWRCTRL, MISCOPT, DIS_LDOLPMODE_TIMERS, 1); + } + + // + // Done with critical section. + // + AM_CRITICAL_END_ASM + +} // am_hal_ctimer_config() + +//***************************************************************************** +// +//! @brief Set up the counter/timer. +//! +//! @param ui32TimerNumber is the number of the Timer that should be +//! configured. +//! +//! @param ui32TimerSegment specifies which segment of the timer should be +//! enabled. +//! +//! @param ui32Configval specifies the configuration options for the selected +//! timer. +//! +//! This function should be used to perform the initial set-up of the +//! counter-timer. It can be used to configure either a 16-bit timer (A or B) or a +//! 32-bit timer using the BOTH option. +//! +//! Valid values for ui32TimerSegment are: +//! +//! AM_HAL_CTIMER_TIMERA +//! AM_HAL_CTIMER_TIMERB +//! AM_HAL_CTIMER_BOTH +//! +//! The timer's clock source, mode, interrupt, and external pin behavior are +//! all controlled through the \e ui32Configval parameter. The valid options +//! for ui32ConfigVal include any ORed together combination of the following: +//! +//! Clock configuration macros: +//! +//! AM_HAL_CTIMER_HFRC_24MHZ +//! AM_HAL_CTIMER_LFRC_512HZ +//! ... etc. (See am_hal_ctimer.h for the full set of options.) +//! +//! Mode selection macros: +//! +//! AM_HAL_CTIMER_FN_ONCE +//! AM_HAL_CTIMER_FN_REPEAT +//! AM_HAL_CTIMER_FN_PWM_ONCE +//! AM_HAL_CTIMER_FN_PWM_REPEAT +//! AM_HAL_CTIMER_FN_CONTINUOUS +//! +//! Interrupt control: +//! +//! AM_HAL_CTIMER_INT_ENABLE +//! +//! Pin control: +//! +//! AM_HAL_CTIMER_PIN_ENABLE +//! AM_HAL_CTIMER_PIN_INVERT +//! +//! ADC trigger (Timer 3 only): +//! +//! AM_HAL_CTIMER_ADC_TRIG +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ctimer_config_single(uint32_t ui32TimerNumber, + uint32_t ui32TimerSegment, + uint32_t ui32ConfigVal) +{ + volatile uint32_t *pui32ConfigReg; + uint32_t ui32WriteVal; + + // + // Find the correct register to write based on the timer number. + // + pui32ConfigReg = (uint32_t *)(AM_REG_CTIMERn(0) + AM_REG_CTIMER_CTRL0_O + + (ui32TimerNumber * TIMER_OFFSET)); + + // + // Begin critical section while config registers are read and modified. + // + AM_CRITICAL_BEGIN_ASM + + // + // Save the value that's already in the register. + // + ui32WriteVal = AM_REGVAL(pui32ConfigReg); + + // + // If we're working with TIMERB, we need to shift our configuration value + // up by 16 bits. + // + + if ( ui32TimerSegment == AM_HAL_CTIMER_TIMERB ) + { + ui32ConfigVal = ((ui32ConfigVal & 0xFFFF) << 16); + } + + // + // Replace part of the saved register value with the configuration value + // from the caller. + // + ui32WriteVal = (ui32WriteVal & ~(ui32TimerSegment)) | ui32ConfigVal; + + // + // If we're configuring both timers, we need to set the "link" bit. + // + if ( ui32TimerSegment == AM_HAL_CTIMER_BOTH ) + { + ui32WriteVal |= AM_HAL_CTIMER_LINK; + } + + // + // Write our completed configuration value. + // + AM_REGVAL(pui32ConfigReg) = ui32WriteVal; + + // + // If all of the clock sources are not HRFC disable LDO when sleeping if timers are enabled. + // + if ( timers_use_hfrc() ) + { + AM_BFW(PWRCTRL, MISCOPT, DIS_LDOLPMODE_TIMERS, 0); + } + else + { + AM_BFW(PWRCTRL, MISCOPT, DIS_LDOLPMODE_TIMERS, 1); + } + + // + // Done with critical section. + // + AM_CRITICAL_END_ASM + +} // am_hal_ctimer_config_single() + +//***************************************************************************** +// +//! @brief Start a timer +//! +//! @param ui32TimerNumber is the number of the timer to enable +//! +//! @param ui32TimerSegment specifies which segment of the timer should be +//! enabled. Valid values for ui32TimerSegment are: +//! AM_HAL_CTIMER_TIMERA +//! AM_HAL_CTIMER_TIMERB +//! AM_HAL_CTIMER_BOTH +//! +//! This function will enable a timer to begin incrementing. The \e +//! ui32TimerNumber parameter selects the timer that should be enabled, for +//! example, a 0 would target TIMER0. The \e ui32TimerSegment parameter allows +//! the caller to individually select a segment within a timer to be enabled, +//! such as TIMER0A, TIMER0B, or both. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ctimer_start(uint32_t ui32TimerNumber, uint32_t ui32TimerSegment) +{ + volatile uint32_t *pui32ConfigReg; + uint32_t ui32ConfigVal; + + // + // Find the correct control register. + // + pui32ConfigReg = (uint32_t *)(AM_REG_CTIMERn(0) + AM_REG_CTIMER_CTRL0_O + + (ui32TimerNumber * TIMER_OFFSET)); + + // + // Begin critical section while config registers are read and modified. + // + AM_CRITICAL_BEGIN_ASM + + // + // Read the current value. + // + ui32ConfigVal = *pui32ConfigReg; + + // + // Clear out the "clear" bit. + // + ui32ConfigVal &= ~(ui32TimerSegment & (AM_REG_CTIMER_CTRL0_TMRA0CLR_M | + AM_REG_CTIMER_CTRL0_TMRB0CLR_M)); + + // + // Set the "enable bit" + // + ui32ConfigVal |= (ui32TimerSegment & (AM_REG_CTIMER_CTRL0_TMRA0EN_M | + AM_REG_CTIMER_CTRL0_TMRB0EN_M)); + + // + // Write the value back to the register. + // + AM_REGVAL(pui32ConfigReg) = ui32ConfigVal; + + // + // Done with critical section. + // + AM_CRITICAL_END_ASM +} // am_hal_ctimer_start() + +//***************************************************************************** +// +//! @brief Stop a timer +//! +//! @param ui32TimerNumber is the number of the timer to disable. +//! +//! @param ui32TimerSegment specifies which segment of the timer should be +//! disabled. +//! +//! This function will stop the selected timer from incrementing. The \e +//! ui32TimerNumber parameter selects the timer that should be disabled, for +//! example, a 0 would target TIMER0. The \e ui32TimerSegment parameter allows +//! the caller to individually select a segment within a timer to be disabled, +//! such as TIMER0A, TIMER0B, or both. +//! +//! This function will stop a counter/timer from counting, but does not return +//! the count value to 'zero'. If you would like to reset the counter back to +//! zero, try the am_hal_ctimer_clear() function instead. +//! +//! Valid values for ui32TimerSegment are: +//! +//! AM_HAL_CTIMER_TIMERA +//! AM_HAL_CTIMER_TIMERB +//! AM_HAL_CTIMER_BOTH +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ctimer_stop(uint32_t ui32TimerNumber, uint32_t ui32TimerSegment) +{ + volatile uint32_t *pui32ConfigReg; + + // + // Find the correct control register. + // + pui32ConfigReg = (uint32_t *)(AM_REG_CTIMERn(0) + AM_REG_CTIMER_CTRL0_O + + (ui32TimerNumber * TIMER_OFFSET)); + + // + // Begin critical section. + // + AM_CRITICAL_BEGIN_ASM + + // + // Clear the "enable" bit + // + AM_REGVAL(pui32ConfigReg) &= ~(ui32TimerSegment & + (AM_REG_CTIMER_CTRL0_TMRA0EN_M | + AM_REG_CTIMER_CTRL0_TMRB0EN_M)); + + // + // Done with critical section. + // + AM_CRITICAL_END_ASM +} // am_hal_ctimer_stop() + +//***************************************************************************** +// +//! @brief Stops a timer and resets its value back to zero. +//! +//! @param ui32TimerNumber is the number of the timer to clear. +//! +//! @param ui32TimerSegment specifies which segment of the timer should be +//! cleared. +//! +//! This function will stop a free-running counter-timer, reset its value to +//! zero, and leave the timer disabled. When you would like to restart the +//! counter, you will need to call am_hal_ctimer_start(). +//! +//! The \e ui32TimerSegment parameter allows the caller to individually select +//! a segment within, such as TIMER0A, TIMER0B, or both. +//! +//! Valid values for ui32TimerSegment are: +//! +//! AM_HAL_CTIMER_TIMERA +//! AM_HAL_CTIMER_TIMERB +//! AM_HAL_CTIMER_BOTH +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ctimer_clear(uint32_t ui32TimerNumber, uint32_t ui32TimerSegment) +{ + volatile uint32_t *pui32ConfigReg; + + // + // Find the correct control register. + // + pui32ConfigReg = (uint32_t *)(AM_REG_CTIMERn(0) + AM_REG_CTIMER_CTRL0_O + + (ui32TimerNumber * TIMER_OFFSET)); + + // + // Begin critical section. + // + AM_CRITICAL_BEGIN_ASM + + // + // Set the "clear" bit + // + AM_REGVAL(pui32ConfigReg) |= (ui32TimerSegment & + (AM_REG_CTIMER_CTRL0_TMRA0CLR_M | + AM_REG_CTIMER_CTRL0_TMRB0CLR_M)); + + // + // Done with critical section. + // + AM_CRITICAL_END_ASM +} // am_hal_ctimer_clear() + +//***************************************************************************** +// +//! @brief Returns the current free-running value of the selected timer. +//! +//! @param ui32TimerNumber is the number of the timer to read. +//! @param ui32TimerSegment specifies which segment of the timer should be +//! read. +//! +//! This function returns the current free-running value of the selected timer. +//! +//! @note When reading from a linked timer, be sure to use AM_HAL_CTIMER both +//! for the segment argument. +//! +//! Valid values for ui32TimerSegment are: +//! +//! AM_HAL_CTIMER_TIMERA +//! AM_HAL_CTIMER_TIMERB +//! AM_HAL_CTIMER_BOTH +//! +//! @return Current timer value. +// +//***************************************************************************** +uint32_t +am_hal_ctimer_read(uint32_t ui32TimerNumber, uint32_t ui32TimerSegment) +{ + volatile uint32_t ui32Value = 0; + uint32_t ui32Values[3] = {0}; + uint32_t ui32TimerAddrTbl[4] = + { + REG_CTIMER_BASEADDR + AM_REG_CTIMER_TMR0_O, + REG_CTIMER_BASEADDR + AM_REG_CTIMER_TMR1_O, + REG_CTIMER_BASEADDR + AM_REG_CTIMER_TMR2_O, + REG_CTIMER_BASEADDR + AM_REG_CTIMER_TMR3_O + }; + + // + // Read the timer with back2back reads. This is a workaround for a clock + // domain synchronization issue. Some timer bits may be slow to increment, + // which means that the value in the timer register will sometimes be + // wrong. + // + // The architecture guarantees that: + // + // 1) If the timer is running at a speed close to the core frequency, the + // core and timer clock domains will be synchronized, and no "bad" reads + // will happen. + // + // 2) Bad reads will only happen if the core reads the timer register while + // the timer value is transitioning from one count to the next. + // + // 3) The timer will resolve to the correct value within one 24 MHz clock + // cycle. + // + // If we read the timer three times in a row with back-to-back load + // instructions, then we can guarantee that the timer will only have time + // to increment once, and that only one of the three reads can be wrong. + // This routine will perform the back-to-back reads and return all three + // values. The rest of this fuction determines which value we should + // actually use. + // + back2back_reads(ui32TimerAddrTbl[ui32TimerNumber], ui32Values); + + // + // Shift or mask the values based on the given timer segment. + // + if ( ui32TimerSegment == AM_HAL_CTIMER_TIMERB ) + { + ui32Values[0] >>= 16; + ui32Values[1] >>= 16; + ui32Values[2] >>= 16; + } + else if ( ui32TimerSegment == AM_HAL_CTIMER_TIMERA ) + { + ui32Values[0] &= 0xFFFF; + ui32Values[1] &= 0xFFFF; + ui32Values[2] &= 0xFFFF; + } + + // + // Now, we'll figure out which of the three values is the correct time. + // + if (ui32Values[0] == ui32Values[1]) + { + // + // If the first two values match, then neither one was a bad read. + // We'll take this as the current time. + // + ui32Value = ui32Values[1]; + } + else + { + // + // If the first two values didn't match, then one of them might be bad. + // If one of the first two values is bad, then the third one should + // always be correct. We'll take the third value as the correct time. + // + ui32Value = ui32Values[2]; + + // + // If all of the statements about the architecture are true, the third + // value should be correct, and it should always be within one count of + // either the first or the second value. + // + // Just in case, we'll check against the previous two values to make + // sure that our final answer was reasonable. If it isn't, we will + // flag it as a "bad read", and fail this assert statement. + // + // This shouldn't ever happen, and it hasn't ever happened in any of + // our tests so far. + // + am_hal_debug_assert_msg((adjacent(ui32Values[1], ui32Values[2]) || + adjacent(ui32Values[0], ui32Values[2])), + "Bad CTIMER read"); + } + + return ui32Value; +} // am_hal_ctimer_read() + +//***************************************************************************** +// +//! @brief Enable output to the timer pin +//! +//! @param ui32TimerNumber is the number of the timer to configure. +//! +//! @param ui32TimerSegment specifies which segment of the timer to use. +//! +//! This function will enable the output pin for the selected timer. The \e +//! ui32TimerSegment parameter allows the caller to individually select a +//! segment within, such as TIMER0A, TIMER0B, or both. +//! +//! Valid values for ui32TimerSegment are: +//! +//! AM_HAL_CTIMER_TIMERA +//! AM_HAL_CTIMER_TIMERB +//! AM_HAL_CTIMER_BOTH +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ctimer_pin_enable(uint32_t ui32TimerNumber, uint32_t ui32TimerSegment) +{ + volatile uint32_t *pui32ConfigReg; + + // + // Find the correct control register. + // + pui32ConfigReg = (uint32_t *)(AM_REG_CTIMERn(0) + AM_REG_CTIMER_CTRL0_O + + (ui32TimerNumber * TIMER_OFFSET)); + + // + // Begin critical section. + // + AM_CRITICAL_BEGIN_ASM + + // + // Set the pin enable bit + // + AM_REGVAL(pui32ConfigReg) |= (ui32TimerSegment & + (AM_REG_CTIMER_CTRL0_TMRA0PE_M | + AM_REG_CTIMER_CTRL0_TMRB0PE_M)); + + // + // Done with critical section. + // + AM_CRITICAL_END_ASM +} // am_hal_ctimer_pin_enable() + +//***************************************************************************** +// +//! @brief Disable the output pin. +//! +//! @param ui32TimerNumber is the number of the timer to configure. +//! +//! @param ui32TimerSegment specifies which segment of the timer to use. +//! +//! This function will disable the output pin for the selected timer. The \e +//! ui32TimerSegment parameter allows the caller to individually select a +//! segment within, such as TIMER0A, TIMER0B, or both. +//! +//! Valid values for ui32TimerSegment are: +//! +//! AM_HAL_CTIMER_TIMERA +//! AM_HAL_CTIMER_TIMERB +//! AM_HAL_CTIMER_BOTH +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ctimer_pin_disable(uint32_t ui32TimerNumber, uint32_t ui32TimerSegment) +{ + volatile uint32_t *pui32ConfigReg; + + // + // Find the correct control register. + // + pui32ConfigReg = (uint32_t *)(AM_REG_CTIMERn(0) + AM_REG_CTIMER_CTRL0_O + + (ui32TimerNumber * TIMER_OFFSET)); + + // + // Begin critical section. + // + AM_CRITICAL_BEGIN_ASM + + // + // Clear the pin enable bit + // + AM_REGVAL(pui32ConfigReg) &= ~(ui32TimerSegment & + (AM_REG_CTIMER_CTRL0_TMRA0PE_M | + AM_REG_CTIMER_CTRL0_TMRB0PE_M)); + + // + // Done with critical section. + // + AM_CRITICAL_END_ASM +} // am_hal_ctimer_pin_disable() + +//***************************************************************************** +// +//! @brief Set the polarity of the output pin. +//! +//! @param ui32TimerNumber is the number of the timer to configure. +//! +//! @param ui32TimerSegment specifies which segment of the timer to use. +//! +//! @param bInvertOutpt determines whether the output should be inverted. If +//! true, the timer output pin for the selected timer segment will be +//! inverted. +//! +//! This function will set the polarity of the the output pin for the selected +//! timer. The \e ui32TimerSegment parameter allows the caller to individually +//! select a segment within, such as TIMER0A, TIMER0B, or both. +//! +//! Valid values for ui32TimerSegment are: +//! +//! AM_HAL_CTIMER_TIMERA +//! AM_HAL_CTIMER_TIMERB +//! AM_HAL_CTIMER_BOTH +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ctimer_pin_invert(uint32_t ui32TimerNumber, uint32_t ui32TimerSegment, + bool bInvertOutput) +{ + volatile uint32_t *pui32ConfigReg; + + // + // Find the correct control register. + // + pui32ConfigReg = (uint32_t *)(AM_REG_CTIMERn(0) + AM_REG_CTIMER_CTRL0_O + + (ui32TimerNumber * TIMER_OFFSET)); + + // + // Begin critical section. + // + AM_CRITICAL_BEGIN_ASM + + // + // Figure out if we're supposed to be setting or clearing the polarity bit. + // + if ( bInvertOutput ) + { + // + // Set the polarity bit to invert the output. + // + AM_REGVAL(pui32ConfigReg) |= (ui32TimerSegment & + (AM_REG_CTIMER_CTRL0_TMRA0POL_M | + AM_REG_CTIMER_CTRL0_TMRB0POL_M)); + } + else + { + // + // Clear the polarity bit. + // + AM_REGVAL(pui32ConfigReg) &= ~(ui32TimerSegment & + (AM_REG_CTIMER_CTRL0_TMRA0POL_M | + AM_REG_CTIMER_CTRL0_TMRB0POL_M)); + } + + // + // Done with critical section. + // + AM_CRITICAL_END_ASM +} // am_hal_ctimer_pin_invert() + +//***************************************************************************** +// +//! @brief Set a compare register. +//! +//! @param ui32TimerNumber is the number of the timer to configure. +//! +//! @param ui32TimerSegment specifies which segment of the timer to use. +//! Valid values for ui32TimerSegment are: +//! +//! AM_HAL_CTIMER_TIMERA +//! AM_HAL_CTIMER_TIMERB +//! AM_HAL_CTIMER_BOTH +//! +//! @param ui32CompareReg specifies which compare register should be set +//! (either 0 or 1) +//! +//! @param ui32Value is the value that should be written to the compare +//! register. +//! +//! This function allows the caller to set the values in the compare registers +//! for a timer. These registers control the period and duty cycle of the +//! timers and their associated output pins. Please see the datasheet for +//! further information on the operation of the compare registers. The \e +//! ui32TimerSegment parameter allows the caller to individually select a +//! segment within, such as TIMER0A, TIMER0B, or both. +//! +//! @note For simple manipulations of period or duty cycle for timers and PWMs, +//! you may find it easier to use the am_hal_ctimer_period_set() function. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ctimer_compare_set(uint32_t ui32TimerNumber, uint32_t ui32TimerSegment, + uint32_t ui32CompareReg, uint32_t ui32Value) +{ + volatile uint32_t *pui32CmprRegA, *pui32CmprRegB; + uint32_t ui32CmprRegA, ui32CmprRegB; + + // + // Find the correct compare register to write. + // Assume A or BOTH. We'll change later if B. + // + pui32CmprRegA = (uint32_t *)(AM_REG_CTIMERn(0) + + AM_REG_CTIMER_CMPRA0_O + + (ui32TimerNumber * TIMER_OFFSET)); + pui32CmprRegB = pui32CmprRegA + CTIMER_CMPR_OFFSET; + + // + // Write the compare register with the selected value. + // Begin critical section while CMPR registers are modified. + // + AM_CRITICAL_BEGIN_ASM + + ui32CmprRegA = *pui32CmprRegA; + ui32CmprRegB = *pui32CmprRegB; + + if ( ui32CompareReg == 1 ) + { + // + // CMPR reg 1 + // Get the lower 16b (but may not be used if TIMERB). + // + ui32CmprRegA = ( (ui32CmprRegA & AM_REG_CTIMER_CMPRA0_CMPR0A0_M) | + AM_REG_CTIMER_CMPRA0_CMPR1A0(ui32Value & 0xFFFF) ); + + // + // Get the upper 16b (but may not be used if TIMERA) + // + ui32CmprRegB = ( (ui32CmprRegB & AM_REG_CTIMER_CMPRA0_CMPR0A0_M) | + AM_REG_CTIMER_CMPRA0_CMPR1A0(ui32Value >> 16) ); + } + else + { + // + // CMPR reg 0 + // Get the lower 16b (but may not be used if TIMERB) + // + ui32CmprRegA = ( (ui32CmprRegA & AM_REG_CTIMER_CMPRA0_CMPR1A0_M) | + AM_REG_CTIMER_CMPRA0_CMPR0A0(ui32Value & 0xFFFF) ); + + // + // Set the upper 16b (but may not be used if TIMERA) + // + ui32CmprRegB = ( (ui32CmprRegB & AM_REG_CTIMER_CMPRA0_CMPR1A0_M) | + AM_REG_CTIMER_CMPRA0_CMPR0A0(ui32Value >> 16) ); + } + + if ( ui32TimerSegment == AM_HAL_CTIMER_TIMERB ) + { + *pui32CmprRegB = ui32CmprRegB; + } + else + { + // + // It's TIMERA or BOTH. + // + *pui32CmprRegA = ui32CmprRegA; + + if ( ui32TimerSegment == AM_HAL_CTIMER_BOTH ) + { + *pui32CmprRegB = ui32CmprRegB; + } + } + + // + // Done with critical section. + // + AM_CRITICAL_END_ASM +} // am_hal_ctimer_compare_set() + +//***************************************************************************** +// +//! @brief Set the period and duty cycle of a timer. +//! +//! @param ui32TimerNumber is the number of the timer to configure. +//! +//! @param ui32TimerSegment specifies which segment of the timer to use. +//! +//! @param ui32Period specifies the desired period. This parameter effectively +//! specifies the CTIMER CMPR field(s). The CMPR fields are handled in hardware +//! as (n+1) values, therefore ui32Period is actually specified as 1 less than +//! the desired period. Finally, as mentioned in the data sheet, the CMPR fields +//! cannot be 0 (a value of 1), so neither can ui32Period be 0. +//! +//! @param ui32OnTime set the number of clocks where the output signal is high. +//! +//! This function should be used for simple manipulations of the period and +//! duty cycle of a counter/timer. To set the period and/or duty cycle of a +//! linked timer pair, use AM_HAL_CTIMER_BOTH as the timer segment argument. If +//! you would like to set the period and/or duty cycle for both TIMERA and +//! TIMERB you will need to call this function twice: once for TIMERA, and once +//! for TIMERB. +//! +//! Valid values for ui32TimerSegment are: +//! +//! AM_HAL_CTIMER_TIMERA +//! AM_HAL_CTIMER_TIMERB +//! AM_HAL_CTIMER_BOTH +//! +//! @note The ui32OnTime parameter will only work if the timer is currently +//! operating in one of the PWM modes. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ctimer_period_set(uint32_t ui32TimerNumber, uint32_t ui32TimerSegment, + uint32_t ui32Period, uint32_t ui32OnTime) +{ + volatile uint32_t *pui32ControlReg; + volatile uint32_t *pui32CompareRegA; + volatile uint32_t *pui32CompareRegB; + uint32_t ui32Mode, ui32Comp0, ui32Comp1; + + // + // Find the correct control register to pull the function select field + // from. + // + pui32ControlReg = (uint32_t *)(AM_REG_CTIMERn(0) + AM_REG_CTIMER_CTRL0_O + + (ui32TimerNumber * TIMER_OFFSET)); + + // + // Find the correct compare registers to write. + // + pui32CompareRegA = (uint32_t *)(AM_REG_CTIMERn(0) + + AM_REG_CTIMER_CMPRA0_O + + (ui32TimerNumber * TIMER_OFFSET)); + + pui32CompareRegB = (uint32_t *)(AM_REG_CTIMERn(0) + + AM_REG_CTIMER_CMPRB0_O + + (ui32TimerNumber * TIMER_OFFSET)); + + // + // Begin critical section. + // + AM_CRITICAL_BEGIN_ASM + + // + // Extract the timer mode from the register based on the ui32TimerSegment + // selected by the user. + // + ui32Mode = *pui32ControlReg; + if ( ui32TimerSegment == AM_HAL_CTIMER_TIMERB ) + { + ui32Mode = ui32Mode >> 16; + } + + // + // Mask to get to the bits we're interested in. + // + ui32Mode = ui32Mode & AM_REG_CTIMER_CTRL0_TMRA0FN_M; + + // + // If the mode is a PWM mode, we'll need to calculate the correct CMPR0 and + // CMPR1 values here. + // + if (ui32Mode == AM_HAL_CTIMER_FN_PWM_ONCE || + ui32Mode == AM_HAL_CTIMER_FN_PWM_REPEAT) + { + ui32Comp0 = ui32Period - ui32OnTime; + ui32Comp1 = ui32Period; + } + else + { + ui32Comp0 = ui32Period; + ui32Comp1 = 0; + } + + // + // Based on the timer segment argument, write the calculated Compare 0 and + // Compare 1 values to the correct halves of the correct registers. + // + if ( ui32TimerSegment == AM_HAL_CTIMER_TIMERA ) + { + // + // For timer A, write the values to the TIMERA compare register. + // + *pui32CompareRegA = (AM_REG_CTIMER_CMPRA0_CMPR0A0(ui32Comp0) | + AM_REG_CTIMER_CMPRA0_CMPR1A0(ui32Comp1)); + } + else if ( ui32TimerSegment == AM_HAL_CTIMER_TIMERB ) + { + // + // For timer B, write the values to the TIMERA compare register. + // + *pui32CompareRegB = (AM_REG_CTIMER_CMPRA0_CMPR0A0(ui32Comp0) | + AM_REG_CTIMER_CMPRA0_CMPR1A0(ui32Comp1)); + } + else + { + // + // For the linked case, write the lower halves of the values to the + // TIMERA compare register, and the upper halves to the TIMERB compare + // register. + // + *pui32CompareRegA = (AM_REG_CTIMER_CMPRA0_CMPR0A0(ui32Comp0) | + AM_REG_CTIMER_CMPRA0_CMPR1A0(ui32Comp1)); + + *pui32CompareRegB = (AM_REG_CTIMER_CMPRA0_CMPR0A0(ui32Comp0 >> 16) | + AM_REG_CTIMER_CMPRA0_CMPR1A0(ui32Comp1 >> 16)); + } + + // + // Done with critical section. + // + AM_CRITICAL_END_ASM +} // am_hal_ctimer_period_set() + +//***************************************************************************** +// +//! @brief Enable the TIMERA3 ADC trigger +//! +//! This function enables the ADC trigger within TIMERA3. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ctimer_adc_trigger_enable(void) +{ + // + // Begin critical section. + // + AM_CRITICAL_BEGIN_ASM + + // + // Enable the ADC trigger. + // + AM_REGn(CTIMER, 0, CTRL3) |= AM_REG_CTIMER_CTRL3_ADCEN_M; + + // + // Done with critical section. + // + AM_CRITICAL_END_ASM +} // am_hal_ctimer_adc_trigger_enable() + +//***************************************************************************** +// +//! @brief Disable the TIMERA3 ADC trigger +//! +//! This function disables the ADC trigger within TIMERA3. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ctimer_adc_trigger_disable(void) +{ + // + // Begin critical section. + // + AM_CRITICAL_BEGIN_ASM + + // + // Disable the ADC trigger. + // + AM_REGn(CTIMER, 0, CTRL3) &= ~AM_REG_CTIMER_CTRL3_ADCEN_M; + + // + // Done with critical section. + // + AM_CRITICAL_END_ASM +} // am_hal_ctimer_adc_trigger_disable() + +//***************************************************************************** +// +//! @brief Enables the selected timer interrupt. +//! +//! @param ui32Interrupt is the interrupt to be used. +//! +//! This function will enable the selected interrupts in the main CTIMER +//! interrupt enable register. In order to receive an interrupt from a timer, +//! you will need to enable the interrupt for that timer in this main register, +//! as well as in the timer control register (accessible though +//! am_hal_ctimer_config()), and in the NVIC. +//! +//! ui32Interrupt should be the logical OR of one or more of the following +//! values: +//! +//! AM_HAL_CTIMER_INT_TIMERA0C0 +//! AM_HAL_CTIMER_INT_TIMERA0C1 +//! AM_HAL_CTIMER_INT_TIMERB0C0 +//! AM_HAL_CTIMER_INT_TIMERB0C1 +//! AM_HAL_CTIMER_INT_TIMERA1C0 +//! AM_HAL_CTIMER_INT_TIMERA1C1 +//! AM_HAL_CTIMER_INT_TIMERB1C0 +//! AM_HAL_CTIMER_INT_TIMERB1C1 +//! AM_HAL_CTIMER_INT_TIMERA2C0 +//! AM_HAL_CTIMER_INT_TIMERA2C1 +//! AM_HAL_CTIMER_INT_TIMERB2C0 +//! AM_HAL_CTIMER_INT_TIMERB2C1 +//! AM_HAL_CTIMER_INT_TIMERA3C0 +//! AM_HAL_CTIMER_INT_TIMERA3C1 +//! AM_HAL_CTIMER_INT_TIMERB3C0 +//! AM_HAL_CTIMER_INT_TIMERB3C1 +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ctimer_int_enable(uint32_t ui32Interrupt) +{ + // + // Begin critical section. + // + AM_CRITICAL_BEGIN_ASM + + // + // Enable the interrupt at the module level. + // + AM_REGn(CTIMER, 0, INTEN) |= ui32Interrupt; + + // + // Done with critical section. + // + AM_CRITICAL_END_ASM +} // am_hal_ctimer_int_enable() + +//***************************************************************************** +// +//! @brief Return the enabled timer interrupts. +//! +//! This function will return all enabled interrupts in the main CTIMER +//! interrupt enable register. +//! +//! @return return enabled interrupts. This will be a logical or of: +//! +//! AM_HAL_CTIMER_INT_TIMERA0C0 +//! AM_HAL_CTIMER_INT_TIMERA0C1 +//! AM_HAL_CTIMER_INT_TIMERB0C0 +//! AM_HAL_CTIMER_INT_TIMERB0C1 +//! AM_HAL_CTIMER_INT_TIMERA1C0 +//! AM_HAL_CTIMER_INT_TIMERA1C1 +//! AM_HAL_CTIMER_INT_TIMERB1C0 +//! AM_HAL_CTIMER_INT_TIMERB1C1 +//! AM_HAL_CTIMER_INT_TIMERA2C0 +//! AM_HAL_CTIMER_INT_TIMERA2C1 +//! AM_HAL_CTIMER_INT_TIMERB2C0 +//! AM_HAL_CTIMER_INT_TIMERB2C1 +//! AM_HAL_CTIMER_INT_TIMERA3C0 +//! AM_HAL_CTIMER_INT_TIMERA3C1 +//! AM_HAL_CTIMER_INT_TIMERB3C0 +//! AM_HAL_CTIMER_INT_TIMERB3C1 +//! +//! @return Return the enabled timer interrupts. +// +//***************************************************************************** +uint32_t +am_hal_ctimer_int_enable_get(void) +{ + // + // Return enabled interrupts. + // + return AM_REGn(CTIMER, 0, INTEN); +} // am_hal_ctimer_int_enable_get() + +//***************************************************************************** +// +//! @brief Disables the selected timer interrupt. +//! +//! @param ui32Interrupt is the interrupt to be used. +//! +//! This function will disable the selected interrupts in the main CTIMER +//! interrupt register. +//! +//! ui32Interrupt should be the logical OR of one or more of the following +//! values: +//! +//! AM_HAL_CTIMER_INT_TIMERA0C0 +//! AM_HAL_CTIMER_INT_TIMERA0C1 +//! AM_HAL_CTIMER_INT_TIMERB0C0 +//! AM_HAL_CTIMER_INT_TIMERB0C1 +//! AM_HAL_CTIMER_INT_TIMERA1C0 +//! AM_HAL_CTIMER_INT_TIMERA1C1 +//! AM_HAL_CTIMER_INT_TIMERB1C0 +//! AM_HAL_CTIMER_INT_TIMERB1C1 +//! AM_HAL_CTIMER_INT_TIMERA2C0 +//! AM_HAL_CTIMER_INT_TIMERA2C1 +//! AM_HAL_CTIMER_INT_TIMERB2C0 +//! AM_HAL_CTIMER_INT_TIMERB2C1 +//! AM_HAL_CTIMER_INT_TIMERA3C0 +//! AM_HAL_CTIMER_INT_TIMERA3C1 +//! AM_HAL_CTIMER_INT_TIMERB3C0 +//! AM_HAL_CTIMER_INT_TIMERB3C1 +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ctimer_int_disable(uint32_t ui32Interrupt) +{ + // + // Begin critical section. + // + AM_CRITICAL_BEGIN_ASM + + // + // Disable the interrupt at the module level. + // + AM_REGn(CTIMER, 0, INTEN) &= ~ui32Interrupt; + + // + // Done with critical section. + // + AM_CRITICAL_END_ASM +} // am_hal_ctimer_int_disable() + +//***************************************************************************** +// +//! @brief Clears the selected timer interrupt. +//! +//! @param ui32Interrupt is the interrupt to be used. +//! +//! This function will clear the selected interrupts in the main CTIMER +//! interrupt register. +//! +//! ui32Interrupt should be the logical OR of one or more of the following +//! values: +//! +//! AM_HAL_CTIMER_INT_TIMERA0C0 +//! AM_HAL_CTIMER_INT_TIMERA0C1 +//! AM_HAL_CTIMER_INT_TIMERB0C0 +//! AM_HAL_CTIMER_INT_TIMERB0C1 +//! AM_HAL_CTIMER_INT_TIMERA1C0 +//! AM_HAL_CTIMER_INT_TIMERA1C1 +//! AM_HAL_CTIMER_INT_TIMERB1C0 +//! AM_HAL_CTIMER_INT_TIMERB1C1 +//! AM_HAL_CTIMER_INT_TIMERA2C0 +//! AM_HAL_CTIMER_INT_TIMERA2C1 +//! AM_HAL_CTIMER_INT_TIMERB2C0 +//! AM_HAL_CTIMER_INT_TIMERB2C1 +//! AM_HAL_CTIMER_INT_TIMERA3C0 +//! AM_HAL_CTIMER_INT_TIMERA3C1 +//! AM_HAL_CTIMER_INT_TIMERB3C0 +//! AM_HAL_CTIMER_INT_TIMERB3C1 +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ctimer_int_clear(uint32_t ui32Interrupt) +{ + // + // Disable the interrupt at the module level. + // + AM_REGn(CTIMER, 0, INTCLR) = ui32Interrupt; +} // am_hal_ctimer_int_clear() + +//***************************************************************************** +// +//! @brief Sets the selected timer interrupt. +//! +//! @param ui32Interrupt is the interrupt to be used. +//! +//! This function will set the selected interrupts in the main CTIMER +//! interrupt register. +//! +//! ui32Interrupt should be the logical OR of one or more of the following +//! values: +//! +//! AM_HAL_CTIMER_INT_TIMERA0C0 +//! AM_HAL_CTIMER_INT_TIMERA0C1 +//! AM_HAL_CTIMER_INT_TIMERB0C0 +//! AM_HAL_CTIMER_INT_TIMERB0C1 +//! AM_HAL_CTIMER_INT_TIMERA1C0 +//! AM_HAL_CTIMER_INT_TIMERA1C1 +//! AM_HAL_CTIMER_INT_TIMERB1C0 +//! AM_HAL_CTIMER_INT_TIMERB1C1 +//! AM_HAL_CTIMER_INT_TIMERA2C0 +//! AM_HAL_CTIMER_INT_TIMERA2C1 +//! AM_HAL_CTIMER_INT_TIMERB2C0 +//! AM_HAL_CTIMER_INT_TIMERB2C1 +//! AM_HAL_CTIMER_INT_TIMERA3C0 +//! AM_HAL_CTIMER_INT_TIMERA3C1 +//! AM_HAL_CTIMER_INT_TIMERB3C0 +//! AM_HAL_CTIMER_INT_TIMERB3C1 +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ctimer_int_set(uint32_t ui32Interrupt) +{ + // + // Set the interrupts. + // + AM_REGn(CTIMER, 0, INTSET) = ui32Interrupt; +} // am_hal_ctimer_int_set() + +//***************************************************************************** +// +//! @brief Returns either the enabled or raw timer interrupt status. +//! +//! This function will return the timer interrupt status. +//! +//! @return bEnabledOnly if true returns the status of the enabled interrupts +//! only. +//! +//! The return value will be the logical OR of one or more of the following +//! values: +//! +//! AM_HAL_CTIMER_INT_TIMERA0C0 +//! AM_HAL_CTIMER_INT_TIMERA0C1 +//! AM_HAL_CTIMER_INT_TIMERB0C0 +//! AM_HAL_CTIMER_INT_TIMERB0C1 +//! AM_HAL_CTIMER_INT_TIMERA1C0 +//! AM_HAL_CTIMER_INT_TIMERA1C1 +//! AM_HAL_CTIMER_INT_TIMERB1C0 +//! AM_HAL_CTIMER_INT_TIMERB1C1 +//! AM_HAL_CTIMER_INT_TIMERA2C0 +//! AM_HAL_CTIMER_INT_TIMERA2C1 +//! AM_HAL_CTIMER_INT_TIMERB2C0 +//! AM_HAL_CTIMER_INT_TIMERB2C1 +//! AM_HAL_CTIMER_INT_TIMERA3C0 +//! AM_HAL_CTIMER_INT_TIMERA3C1 +//! AM_HAL_CTIMER_INT_TIMERB3C0 +//! AM_HAL_CTIMER_INT_TIMERB3C1 +//! +//! @return Returns either the timer interrupt status. +// +//***************************************************************************** +uint32_t +am_hal_ctimer_int_status_get(bool bEnabledOnly) +{ + // + // Return the desired status. + // + + if ( bEnabledOnly ) + { + uint32_t u32RetVal; + + // + // Begin critical section. + // + AM_CRITICAL_BEGIN_ASM + + u32RetVal = AM_REGn(CTIMER, 0, INTSTAT); + u32RetVal &= AM_REGn(CTIMER, 0, INTEN); + + // + // Done with critical section. + // + AM_CRITICAL_END_ASM + + return u32RetVal; + } + else + { + return AM_REGn(CTIMER, 0, INTSTAT); + } +} // am_hal_ctimer_int_status_get() + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_ctimer.h b/bsp/apollo2/libraries/drivers/hal/am_hal_ctimer.h new file mode 100644 index 0000000000..fa1ebe16c4 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_ctimer.h @@ -0,0 +1,278 @@ +//***************************************************************************** +// +// am_hal_ctimer.h +//! @file +//! +//! @brief Functions for accessing and configuring the CTIMER. +//! +//! @addtogroup ctimer2 Counter/Timer (CTIMER) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_CTIMER_H +#define AM_HAL_CTIMER_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +//! Number of timers +// +//***************************************************************************** +#define AM_HAL_CTIMER_TIMERS_NUM 4 + +//***************************************************************************** +// +//! Timer offset value +// +//***************************************************************************** +#define AM_HAL_CTIMER_TIMER_OFFSET (AM_REG_CTIMER_TMR1_O - AM_REG_CTIMER_TMR0_O) + +//***************************************************************************** +// +//! @name Interrupt Status Bits +//! @brief Interrupt Status Bits for enable/disble use +//! +//! These macros may be used to set and clear interrupt bits +//! @{ +// +//***************************************************************************** +#define AM_HAL_CTIMER_INT_TIMERA0C0 AM_REG_CTIMER_INTEN_CTMRA0C0INT_M +#define AM_HAL_CTIMER_INT_TIMERA0C1 AM_REG_CTIMER_INTEN_CTMRA0C1INT_M +#define AM_HAL_CTIMER_INT_TIMERA1C0 AM_REG_CTIMER_INTEN_CTMRA1C0INT_M +#define AM_HAL_CTIMER_INT_TIMERA1C1 AM_REG_CTIMER_INTEN_CTMRA1C1INT_M +#define AM_HAL_CTIMER_INT_TIMERA2C0 AM_REG_CTIMER_INTEN_CTMRA2C0INT_M +#define AM_HAL_CTIMER_INT_TIMERA2C1 AM_REG_CTIMER_INTEN_CTMRA2C1INT_M +#define AM_HAL_CTIMER_INT_TIMERA3C0 AM_REG_CTIMER_INTEN_CTMRA3C0INT_M +#define AM_HAL_CTIMER_INT_TIMERA3C1 AM_REG_CTIMER_INTEN_CTMRA3C1INT_M + +#define AM_HAL_CTIMER_INT_TIMERB0C0 AM_REG_CTIMER_INTEN_CTMRB0C0INT_M +#define AM_HAL_CTIMER_INT_TIMERB0C1 AM_REG_CTIMER_INTEN_CTMRB0C1INT_M +#define AM_HAL_CTIMER_INT_TIMERB1C0 AM_REG_CTIMER_INTEN_CTMRB1C0INT_M +#define AM_HAL_CTIMER_INT_TIMERB1C1 AM_REG_CTIMER_INTEN_CTMRB1C1INT_M +#define AM_HAL_CTIMER_INT_TIMERB2C0 AM_REG_CTIMER_INTEN_CTMRB2C0INT_M +#define AM_HAL_CTIMER_INT_TIMERB2C1 AM_REG_CTIMER_INTEN_CTMRB2C1INT_M +#define AM_HAL_CTIMER_INT_TIMERB3C0 AM_REG_CTIMER_INTEN_CTMRB3C0INT_M +#define AM_HAL_CTIMER_INT_TIMERB3C1 AM_REG_CTIMER_INTEN_CTMRB3C1INT_M + +// +// Deprecated, use the newer macros above. +// +#define AM_HAL_CTIMER_INT_TIMERA0 AM_HAL_CTIMER_INT_TIMERA0C0 +#define AM_HAL_CTIMER_INT_TIMERB0 AM_HAL_CTIMER_INT_TIMERB0C0 +#define AM_HAL_CTIMER_INT_TIMERA1 AM_HAL_CTIMER_INT_TIMERA1C0 +#define AM_HAL_CTIMER_INT_TIMERB1 AM_HAL_CTIMER_INT_TIMERB1C0 +#define AM_HAL_CTIMER_INT_TIMERA2 AM_HAL_CTIMER_INT_TIMERA2C0 +#define AM_HAL_CTIMER_INT_TIMERB2 AM_HAL_CTIMER_INT_TIMERB2C0 +#define AM_HAL_CTIMER_INT_TIMERA3 AM_HAL_CTIMER_INT_TIMERA3C0 +#define AM_HAL_CTIMER_INT_TIMERB3 AM_HAL_CTIMER_INT_TIMERB3C0 +//! @} + +//***************************************************************************** +// +//! @name Configuration options +//! @brief Configuration options for \e am_hal_ctimer_config_t +//! +//! These options are to be used with the \e am_hal_ctimer_config_t structure +//! used by \e am_hal_ctimer_config +//! @{ +// +//***************************************************************************** +#define AM_HAL_CTIMER_CLK_PIN AM_REG_CTIMER_CTRL0_TMRA0CLK(0x0) +#define AM_HAL_CTIMER_HFRC_12MHZ AM_REG_CTIMER_CTRL0_TMRA0CLK(0x1) +#define AM_HAL_CTIMER_HFRC_3MHZ AM_REG_CTIMER_CTRL0_TMRA0CLK(0x2) +#define AM_HAL_CTIMER_HFRC_187_5KHZ AM_REG_CTIMER_CTRL0_TMRA0CLK(0x3) +#define AM_HAL_CTIMER_HFRC_47KHZ AM_REG_CTIMER_CTRL0_TMRA0CLK(0x4) +#define AM_HAL_CTIMER_HFRC_12KHZ AM_REG_CTIMER_CTRL0_TMRA0CLK(0x5) +#define AM_HAL_CTIMER_XT_32_768KHZ AM_REG_CTIMER_CTRL0_TMRA0CLK(0x6) +#define AM_HAL_CTIMER_XT_16_384KHZ AM_REG_CTIMER_CTRL0_TMRA0CLK(0x7) +#define AM_HAL_CTIMER_XT_2_048KHZ AM_REG_CTIMER_CTRL0_TMRA0CLK(0x8) +#define AM_HAL_CTIMER_XT_256HZ AM_REG_CTIMER_CTRL0_TMRA0CLK(0x9) +#define AM_HAL_CTIMER_LFRC_512HZ AM_REG_CTIMER_CTRL0_TMRA0CLK(0xA) +#define AM_HAL_CTIMER_LFRC_32HZ AM_REG_CTIMER_CTRL0_TMRA0CLK(0xB) +#define AM_HAL_CTIMER_LFRC_1HZ AM_REG_CTIMER_CTRL0_TMRA0CLK(0xC) +#define AM_HAL_CTIMER_LFRC_1_16HZ AM_REG_CTIMER_CTRL0_TMRA0CLK(0xD) +#define AM_HAL_CTIMER_RTC_100HZ AM_REG_CTIMER_CTRL0_TMRA0CLK(0xE) +#define AM_HAL_CTIMER_HCLK AM_REG_CTIMER_CTRL0_TMRA0CLK(0xF) +#define AM_HAL_CTIMER_BUCK AM_REG_CTIMER_CTRL0_TMRA0CLK(0x10) +//! @} + +//***************************************************************************** +// +// Timer function macros. +// +//***************************************************************************** +#define AM_HAL_CTIMER_FN_ONCE AM_REG_CTIMER_CTRL0_TMRA0FN(0) +#define AM_HAL_CTIMER_FN_REPEAT AM_REG_CTIMER_CTRL0_TMRA0FN(1) +#define AM_HAL_CTIMER_FN_PWM_ONCE AM_REG_CTIMER_CTRL0_TMRA0FN(2) +#define AM_HAL_CTIMER_FN_PWM_REPEAT AM_REG_CTIMER_CTRL0_TMRA0FN(3) +#define AM_HAL_CTIMER_FN_CONTINUOUS AM_REG_CTIMER_CTRL0_TMRA0FN(4) + +//***************************************************************************** +// +// Half-timer options. +// +//***************************************************************************** +#define AM_HAL_CTIMER_INT_ENABLE AM_REG_CTIMER_CTRL0_TMRA0IE0_M +#define AM_HAL_CTIMER_PIN_ENABLE AM_REG_CTIMER_CTRL0_TMRA0PE_M +#define AM_HAL_CTIMER_PIN_INVERT AM_REG_CTIMER_CTRL0_TMRA0POL_M +#define AM_HAL_CTIMER_CLEAR AM_REG_CTIMER_CTRL0_TMRA0CLR_M + +//***************************************************************************** +// +// Additional timer options. +// +//***************************************************************************** +#define AM_HAL_CTIMER_LINK AM_REG_CTIMER_CTRL0_CTLINK0_M +#define AM_HAL_CTIMER_ADC_TRIG AM_REG_CTIMER_CTRL3_ADCEN_M + +//***************************************************************************** +// +// Timer selection macros. +// +//***************************************************************************** +#define AM_HAL_CTIMER_TIMERA 0x0000FFFF +#define AM_HAL_CTIMER_TIMERB 0xFFFF0000 +#define AM_HAL_CTIMER_BOTH 0xFFFFFFFF +//! @} + +//***************************************************************************** +// +// Timer configuration structure +// +//***************************************************************************** +typedef struct +{ + // + //! Set to 1 to operate this timer as a 32-bit timer instead of two 16-bit + //! timers. + // + uint32_t ui32Link; + + // + //! Configuration options for TIMERA + // + uint32_t ui32TimerAConfig; + + // + //! Configuration options for TIMERB + // + uint32_t ui32TimerBConfig; + +} +am_hal_ctimer_config_t; + +//***************************************************************************** +// +// Function pointer type for CTimer interrupt handlers. +// +//***************************************************************************** +typedef void (*am_hal_ctimer_handler_t)(void); + +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern void am_hal_ctimer_config(uint32_t ui32TimerNumber, + am_hal_ctimer_config_t *psConfig); + +extern void am_hal_ctimer_config_single(uint32_t ui32TimerNumber, + uint32_t ui32TimerSegment, + uint32_t ui32ConfigVal); + +extern void am_hal_ctimer_start(uint32_t ui32TimerNumber, + uint32_t ui32TimerSegment); + +extern void am_hal_ctimer_stop(uint32_t ui32TimerNumber, + uint32_t ui32TimerSegment); + +extern void am_hal_ctimer_clear(uint32_t ui32TimerNumber, + uint32_t ui32TimerSegment); + +extern uint32_t am_hal_ctimer_read(uint32_t ui32TimerNumber, + uint32_t ui32TimerSegment); + +extern void am_hal_ctimer_pin_enable(uint32_t ui32TimerNumber, + uint32_t ui32TimerSegment); + +extern void am_hal_ctimer_pin_disable(uint32_t ui32TimerNumber, + uint32_t ui32TimerSegment); + +extern void am_hal_ctimer_pin_invert(uint32_t ui32TimerNumber, + uint32_t ui32TimerSegment, + bool bInvertOutput); + +extern void am_hal_ctimer_compare_set(uint32_t ui32TimerNumber, + uint32_t ui32TimerSegment, + uint32_t ui32CompareReg, + uint32_t ui32Value); + +extern void am_hal_ctimer_period_set(uint32_t ui32TimerNumber, + uint32_t ui32TimerSegment, + uint32_t ui32Period, + uint32_t ui32OnTime); + +extern void am_hal_ctimer_adc_trigger_enable(void); +extern void am_hal_ctimer_adc_trigger_disable(void); +extern void am_hal_ctimer_int_enable(uint32_t ui32Interrupt); +extern uint32_t am_hal_ctimer_int_enable_get(void); +extern void am_hal_ctimer_int_disable(uint32_t ui32Interrupt); +extern void am_hal_ctimer_int_set(uint32_t ui32Interrupt); +extern void am_hal_ctimer_int_clear(uint32_t ui32Interrupt); +extern uint32_t am_hal_ctimer_int_status_get(bool bEnabledOnly); +extern void am_hal_ctimer_int_register(uint32_t ui32Interrupt, + am_hal_ctimer_handler_t pfnHandler); +extern void am_hal_ctimer_int_service(uint32_t ui32Status); + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_CTIMER_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_debug.c b/bsp/apollo2/libraries/drivers/hal/am_hal_debug.c new file mode 100644 index 0000000000..4078b5a5a0 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_debug.c @@ -0,0 +1,81 @@ +//***************************************************************************** +// +// am_hal_debug.c +//! @file +//! +//! @brief Useful functions for debugging. +//! +//! These functions and macros were created to assist with debugging. They are +//! intended to be as unintrusive as possible and designed to be removed from +//! the compilation of a project when they are no longer needed. +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +//! @brief Default implementation of a failed ASSERT statement. +//! +//! @param pcFile is the name of the source file where the error occurred. +//! @param ui32Line is the line number where the error occurred. +//! @param pcMessage is an optional message describing the failure. +//! +//! This function is called by am_hal_debug_assert() macro when the supplied +//! condition is not true. The implementation here simply halts the application +//! for further analysis. Individual applications may define their own +//! implementations of am_hal_debug_error() to provide more detailed feedback +//! about the failed am_hal_debug_assert() statement. +//! +//! @return +// +//***************************************************************************** +#if defined (__IAR_SYSTEMS_ICC__) +__weak void +#else +void __attribute__((weak)) +#endif +am_hal_debug_error(const char *pcFile, uint32_t ui32Line, const char *pcMessage) +{ + // + // Halt for analysis. + // + while(1); +} diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_debug.h b/bsp/apollo2/libraries/drivers/hal/am_hal_debug.h new file mode 100644 index 0000000000..a482799c4f --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_debug.h @@ -0,0 +1,89 @@ +//***************************************************************************** +// +// am_hal_debug.h +//! @file +//! +//! @brief Useful macros for debugging. +//! +//! These functions and macros were created to assist with debugging. They are +//! intended to be as unintrusive as possible and designed to be removed from +//! the compilation of a project when they are no longer needed. +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_DEBUG_H +#define AM_HAL_DEBUG_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Debug assert macros. +// +//***************************************************************************** +#ifndef AM_HAL_DEBUG_NO_ASSERT + +#define am_hal_debug_assert_msg(bCondition, pcMessage) \ + if ( !(bCondition)) am_hal_debug_error(__FILE__, __LINE__, pcMessage) + +#define am_hal_debug_assert(bCondition) \ + if ( !(bCondition)) am_hal_debug_error(__FILE__, __LINE__, 0) + +#else + +#define am_hal_debug_assert_msg(bCondition, pcMessage) +#define am_hal_debug_assert(bCondition) + +#endif // AM_DEBUG_ASSERT + +//***************************************************************************** +// +// External function prototypes. +// +//***************************************************************************** +extern void am_hal_debug_error(const char *pcFile, uint32_t ui32Line, + const char *pcMessage); + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_DEBUG_H + diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_flash.c b/bsp/apollo2/libraries/drivers/hal/am_hal_flash.c new file mode 100644 index 0000000000..cd38da812c --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_flash.c @@ -0,0 +1,1449 @@ +//***************************************************************************** +// +// am_hal_flash.c +//! @file +//! +//! @brief Functions for performing Flash operations. +//! +//! @addtogroup flash2 Flash +//! @ingroup apollo2hal +//! +//! IMPORTANT: Interrupts are active during execution of all HAL flash +//! functions. If an interrupt occurs during execution of a flash function +//! that programs or erases flash or INFO space, errors will occur if the +//! interrupt service routine (ISR) is located in on-chip flash. +//! If interrupts are expected during execution of a flash function that +//! programs or erases either flash or INFO space: +//! - Interrupts must be disabled via a critical section handler prior to +//! calling the flash function. +//! - Alternatively, applicable ISRs must be located in non-flash address space +//! (i.e. SRAM, off-chip ROM, etc.). +//! +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +// +// Look-up table +// +g_am_hal_flash_t g_am_hal_flash = +{ + // + // The basics. + // + // flash_mass_erase() + ((int (*) (uint32_t, uint32_t)) 0x0800004d), + // flash_page_erase() + ((int (*) (uint32_t, uint32_t, uint32_t)) 0x08000051), + // flash_program_main() + ((int (*) (uint32_t, uint32_t *, uint32_t *, uint32_t)) 0x08000055), + // flash_program_info() + ((int (*) (uint32_t, uint32_t, uint32_t *, uint32_t, uint32_t)) 0x08000059), + + // + // Non-blocking variants, but be careful these are not interrupt safe so + // mask interrupts while these very long operations proceed. + // + // flash_mass_erase_nb() + ((int (*)(uint32_t, uint32_t)) 0x0800006d), + // flash_page_erase_nb() + ((int (*)(uint32_t, uint32_t, uint32_t)) 0x08000071), + // flash_nb_operation_complete() + ((bool (*)(void)) 0x0800007d), + + // + // Essentially these are recovery options. + // + // flash_erase_info() + ((int (*)(uint32_t, uint32_t)) 0x08000081), + // flash_erase_main_plus_info() + ((int (*)(uint32_t, uint32_t)) 0x08000089), + // flash_erase_main_plus_info_both_instances() + ((int (*)(uint32_t)) 0x08000091), + // flash_recovery() + ((void (*)(uint32_t)) 0x08000099), + + // + // Useful utilities. + // + // flash_util_read_word() + ((uint32_t (*)(uint32_t*)) 0x08000075), + // flash_util_write_word() + ((void (*)(uint32_t*, uint32_t)) 0x08000079), + // delay_cycles() + ((void (*)(uint32_t)) 0x0800009d), + + // + // The following functions pointers must never be called from user + // programs. They are here primarily to document these entry points + // which are usable from a debugger or debugger script. + // + // flash_program_main_sram() + ((void (*) (void)) 0x0800005d), + // flash_program_info_sram() + ((void (*) (void)) 0x08000061), + // flash_erase_main_pages_sram() + ((void (*) (void)) 0x08000065), + // flash_mass_erase_sram() + ((void (*) (void)) 0x08000069), + // flash_erase_info_sram() + ((void (*)(void)) 0x08000085), + // flash_erase_main_plus_info_sram() + ((void (*)(void)) 0x0800008d) +}; + +//***************************************************************************** +// +//! @brief This function performs a mass erase on a flash instance. +//! +//! @param ui32Value - The flash program key. +//! @param ui32FlashInst - The flash instance to erase. +//! +//! This function will erase the desired instance of flash. +//! +//! @note For Apollo2, each flash instance contains a maximum of 512KB. +//! +//! @note Interrupts are active during execution of this function. Any interrupt +//! taken could cause execution errors. Please see the IMPORTANT note under +//! Detailed Description above for more details. +//! +//! @return 0 for success, non-zero for failure. +// +//***************************************************************************** +int +am_hal_flash_mass_erase(uint32_t ui32Value, uint32_t ui32FlashInst) +{ + return g_am_hal_flash.flash_mass_erase(ui32Value, ui32FlashInst); +} + +//***************************************************************************** +// +//! @brief This function performs a page erase on a flash instance. +//! +//! @param ui32Value - The flash program key. +//! @param ui32FlashInst - The flash instance to reference the page number with. +//! @param ui32PageNum - The flash page relative to the specified instance. +//! +//! This function will erase the desired flash page in the desired instance of +//! flash. +//! +//! @note For Apollo2, each flash page is 8KB (or AM_HAL_FLASH_PAGE_SIZE). +//! Each flash instance contains a maximum of 64 pages (or +//! AM_HAL_FLASH_INSTANCE_PAGES). +//! +//! @note When given an absolute flash address, a couple of helpful macros can +//! be utilized when calling this function. +//! For example: +//! am_hal_flash_page_erase(AM_HAL_FLASH_PROGRAM_KEY, +//! AM_HAL_FLASH_ADDR2INST(ui32Addr), +//! AM_HAL_FLASH_ADDR2PAGE(ui32Addr) ); +//! +//! @note Interrupts are active during execution of this function. Any interrupt +//! taken could cause execution errors. Please see the IMPORTANT note under +//! Detailed Description above for more details. +//! +//! @return 0 for success, non-zero for failure. +// +//***************************************************************************** +int +am_hal_flash_page_erase(uint32_t ui32Value, uint32_t ui32FlashInst, + uint32_t ui32PageNum) +{ + return g_am_hal_flash.flash_page_erase(ui32Value, + ui32FlashInst, + ui32PageNum); +} + +//***************************************************************************** +// +//! @brief This programs up to N words of the Main array on one flash instance. +//! +//! @param ui32Value - The programming key, AM_HAL_FLASH_PROGRAM_KEY. +//! @param pui32Src - Pointer to word aligned array of data to program into +//! the flash instance. +//! @param pui32Dst - Pointer to the word aligned flash location where +//! programming of the flash instance is to begin. +//! @param ui32NumWords - The number of words to be programmed. +//! +//! This function will program multiple words in main flash. +//! +//! @note Interrupts are active during execution of this function. Any interrupt +//! taken could cause execution errors. Please see the IMPORTANT note under +//! Detailed Description above for more details. +//! +//! @return 0 for success, non-zero for failure. +// +//***************************************************************************** +int +am_hal_flash_program_main(uint32_t ui32Value, uint32_t *pui32Src, + uint32_t *pui32Dst, uint32_t ui32NumWords) +{ + return g_am_hal_flash.flash_program_main(ui32Value, pui32Src, + pui32Dst, ui32NumWords); +} + +//***************************************************************************** +// +//! @brief This function programs multiple words in the customer INFO space. +//! +//! @param ui32Value - The customer INFO space key. +//! @param ui32InfoInst - The INFO space instance, 0 or 1. +//! @param *pui32Src - Pointer to word aligned array of data to program into +//! the customer INFO space. +//! @param ui32Offset - Word offset into customer INFO space (offset of 0 is +//! the first word, 1 is second word, etc.). +//! @param ui32NumWords - The number of words to be programmed, must not +//! exceed AM_HAL_FLASH_INFO_SIZE/4. +//! +//! This function will program multiple words in the customer INFO space. +//! +//! @note Interrupts are active during execution of this function. Any interrupt +//! taken could cause execution errors. Please see the IMPORTANT note under +//! Detailed Description above for more details. +//! +//! @return 0 for success, non-zero for failure. +// +//***************************************************************************** +int +am_hal_flash_program_info(uint32_t ui32Value, uint32_t ui32InfoInst, + uint32_t *pui32Src, uint32_t ui32Offset, + uint32_t ui32NumWords) +{ + return g_am_hal_flash.flash_program_info(ui32Value, 0, pui32Src, + ui32Offset, ui32NumWords); +} + +//***************************************************************************** +// +//! @brief This function erases an instance of the customer INFO space. +//! +//! @param ui32ProgramKey - The customer INFO space programming key +//! (AM_HAL_FLASH_PROGRAM_KEY). +//! @param ui32Inst - The flash instance, either 0 or 1. +//! +//! This function will erase the the customer INFO space of the specified +//! instance. +//! +//! @note Interrupts are active during execution of this function. Any interrupt +//! taken could cause execution errors. Please see the IMPORTANT note under +//! Detailed Description above for more details. +//! +//! @return 0 for success, non-zero for failure. +// +//***************************************************************************** +int +am_hal_flash_erase_info(uint32_t ui32ProgramKey, + uint32_t ui32Inst) +{ + return g_am_hal_flash.flash_erase_info(ui32ProgramKey, ui32Inst); +} + +//***************************************************************************** +// +//! @brief This function erases the main instance + the customer INFO space. +//! +//! @param ui32ProgramKey - The customer INFO space key. +//! @param ui32Inst - The flash instance, either 0 or 1. +//! +//! This function will erase the main flash + the customer INFO space of the +//! specified instance. +//! +//! @note Interrupts are active during execution of this function. Any interrupt +//! taken could cause execution errors. Please see the IMPORTANT note under +//! Detailed Description above for more details. +//! +//! @return 0 for success, non-zero for failure. +// +//***************************************************************************** +int +am_hal_flash_erase_main_plus_info(uint32_t ui32ProgramKey, + uint32_t ui32Inst) +{ + return g_am_hal_flash.flash_erase_main_plus_info(ui32ProgramKey, + ui32Inst); +} + +//***************************************************************************** +// +//! @brief This function erases the main flash + the customer INFO space. +//! +//! @param ui32ProgramKey - The customer INFO space key. +//! +//! This function will erase both instances the main flash + the +//! customer INFO space. +//! +//! @note Interrupts are active during execution of this function. Any interrupt +//! taken could cause execution errors. Please see the IMPORTANT note under +//! Detailed Description above for more details. +//! +//! @return 0 for success, non-zero for failure. +// +//***************************************************************************** +int +am_hal_flash_erase_main_plus_info_both_instances(uint32_t ui32ProgramKey) +{ + return g_am_hal_flash.flash_erase_main_plus_info_both_instances( + ui32ProgramKey); +} + +//***************************************************************************** +// +//! @brief This function erases both main flash instances + both customer INFO +//! space instances. +//! +//! @param ui32RecoveryKey - The recovery key. +//! +//! This function erases both main instances and both customer INFOinstances +//! even if the customer INFO space is programmed to not be erasable. This +//! function completely erases the flash main and info instances and wipes the +//! SRAM. Upon completion of the erasure operations, it does a POI (power on +//! initialization) reset. +//! +//! @note Interrupts are active during execution of this function. Any interrupt +//! taken could cause execution errors. Please see the IMPORTANT note under +//! Detailed Description above for more details. +//! +//! @return Never Returns!!! +// +//***************************************************************************** +void +am_hal_flash_recovery(uint32_t ui32RecoveryKey) +{ + g_am_hal_flash.flash_recovery(ui32RecoveryKey); +} + +//***************************************************************************** +// +//! @brief Return ui32 value obtained from anywhere in D Code or System Bus +//! +//! @param ui32Address - return the value corresponding to this location. +//! +//! Use this function to read a value from various peripheral locations +//! that must be read from code running external to flash. +//! +//! @return the value found +// +//***************************************************************************** +uint32_t +am_hal_flash_load_ui32(uint32_t ui32Address) +{ + return g_am_hal_flash.flash_util_read_word((uint32_t*)ui32Address); +} + +//***************************************************************************** +// +//! @brief Use the bootrom to write to a location in SRAM or the system bus. +//! +//! @param ui32Address - Store the data value corresponding to this location. +//! @param ui32Data - 32-bit Data to be stored. +//! +//! Use this function to store a value to various peripheral or SRAM locations +//! that can not be touched from code running in SRAM or FLASH. There is no +//! known need for this function in Apollo2 at this time. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_flash_store_ui32(uint32_t ui32Address, uint32_t ui32Data) +{ + g_am_hal_flash.flash_util_write_word((uint32_t*)ui32Address, + ui32Data); +} + +//***************************************************************************** +// +//! @brief Use the bootrom to implement a spin loop. +//! +//! @param ui32Iterations - Number of iterations to delay. +//! +//! Use this function to implement a CPU busy waiting spin loop without cache +//! or delay uncertainties. +//! +//! Note that the ROM-based function executes at 3 cycles per iteration plus +//! the regular function call, entry, and exit overhead. +//! The call and return overhead, including the call to this function, is +//! somewhere in the neighborhood of 14 cycles, or 4.7 iterations. +//! +//! Example: +//! - MCU operating at 48MHz -> 20.83 ns / cycle +//! - Therefore each iteration (once inside the bootrom function) will consume +//! 62.5ns. +//! - The total overhead (assuming 14 cycles) is 292ns. +//! - For ui32Iterations=28: Total delay time = 0.292 + (0.0625 * 28) = 2.04us. +//! +//! The FLASH_CYCLES_US(n) macro can be used with am_hal_flash_delay() to +//! get an approximate microsecond delay. +//! e.g. For a 2us delay, use: +//! am_hal_flash_delay( FLASH_CYCLES_US(2) ); +//! +//! @note Interrupts are active during execution of this function. Therefore, +//! any interrupt taken will affect the delay timing. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_flash_delay(uint32_t ui32Iterations) +{ + g_am_hal_flash.delay_cycles(ui32Iterations); +} + +//***************************************************************************** +// +//! @brief Static Helper Function to check customer info valid bits erasure. +//! +//! Use this function to test the state of the 128 valid bits at the beginning +//! of customer info space. If these are all erased then return true. +//! +//! @return true if the customer info bits are currently erased. +// +//***************************************************************************** +static bool +customer_info_signature_erased(void) +{ + uint32_t *pui32Signature = (uint32_t *) AM_HAL_FLASH_INFO_ADDR; + + return ( (pui32Signature[3] == 0xFFFFFFFF) && + (pui32Signature[2] == 0xFFFFFFFF) && + (pui32Signature[1] == 0xFFFFFFFF) && + (pui32Signature[0] == 0xFFFFFFFF) ) ? true : false; +} + +//***************************************************************************** +// +//! @brief Static Helper Function to set customer info valid bits +//! +//! Use this function to set the state of the 128 valid bits at the beginning +//! of customer info space. If these bits are not set correctly then the +//! customer protection bits in the INFO space will not be honored by the +//! hardware. +//! +//! @return Zero for success. Non-Zero for errors. +// +//***************************************************************************** +static int +customer_info_signature_set(void) +{ + uint32_t ui32Valid[4]; + int iRC; + + // + // If they are already set then we are done. + // + if ( am_hal_flash_customer_info_signature_check() ) + { + return 0; + } + + // + // If they are not erased at this point we have an error. + // + if ( !customer_info_signature_erased() ) + { + return (2 << 16); + } + + // + // OK they need to be set so do it. + // + ui32Valid[3] = AM_HAL_FLASH_INFO_SIGNATURE3; + ui32Valid[2] = AM_HAL_FLASH_INFO_SIGNATURE2; + ui32Valid[1] = AM_HAL_FLASH_INFO_SIGNATURE1; + ui32Valid[0] = AM_HAL_FLASH_INFO_SIGNATURE0; + + iRC = g_am_hal_flash.flash_program_info(AM_HAL_FLASH_PROGRAM_KEY, + 0, // instance + ui32Valid, // source data + 0, // offset + 4); // number of words + return iRC | ((iRC) ? (1 << 16) : 0); +} + +//***************************************************************************** +// +//! @brief Check that the customer info bits are valid. +//! +//! Use this function to test the state of the 128 valid bits at the beginning +//! of customer info space. If these are not set correctly then the customer +//! protection bits in the INFO space will not be honored by the hardware. +//! +//! @return true if valid. +// +//***************************************************************************** +bool +am_hal_flash_customer_info_signature_check(void) +{ + uint32_t *pui32Signature = (uint32_t *)AM_HAL_FLASH_INFO_ADDR; + + return ( (pui32Signature[3] == AM_HAL_FLASH_INFO_SIGNATURE3) && + (pui32Signature[2] == AM_HAL_FLASH_INFO_SIGNATURE2) && + (pui32Signature[1] == AM_HAL_FLASH_INFO_SIGNATURE1) && + (pui32Signature[0] == AM_HAL_FLASH_INFO_SIGNATURE0) ); +} + +//***************************************************************************** +// +//! @brief INFO signature set. +//! +//! Use this function to set the state of the 128 valid bits at the beginning +//! of customer info space, if needed. +//! +//! @note Interrupts are active during execution of this function. Any interrupt +//! taken could cause execution errors. Please see the IMPORTANT note under +//! Detailed Description above for more details. +//! +//! @return Zero for success. Non-Zero for errors. +// +//***************************************************************************** +bool +am_hal_flash_info_signature_set(void) +{ + // + // Check and set signature. + // + return customer_info_signature_set() ? false : true; +} + +//***************************************************************************** +// +//! @brief Disable FLASH INFO space. +//! +//! Use this function to set the state of the 128 valid bits at the beginning +//! of customer info space, if needed. Then disable FLASH erasure. +//! +//! @note Interrupts are active during execution of this function. Any interrupt +//! taken could cause execution errors. Please see the IMPORTANT note under +//! Detailed Description above for more details. +//! +//! @return Zero for success. Non-Zero for errors. +// +//***************************************************************************** +int32_t +am_hal_flash_info_erase_disable(void) +{ + int iRC; + uint32_t ui32SecurityValue; + + // + // Security protection only works if the signature data is correct. + // + iRC = customer_info_signature_set(); + if ( iRC ) + { + return iRC; + } + + // + // Clear bit in INFO space to disable erasure. + // + ui32SecurityValue = AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & + ~AM_HAL_FLASH_INFO_SECURITY_ENINFOERASE_M; + + // + // Now write the word to the flash INFO space. + // + return g_am_hal_flash.flash_program_info( + AM_HAL_FLASH_PROGRAM_KEY, + 0, // instance + &ui32SecurityValue, // source data + AM_HAL_FLASH_INFO_SECURITY_O / 4, // word offset + 1 ); // number of words +} + +//***************************************************************************** +// +//! @brief Check for Disabled FLASH INFO space. +//! +//! Use this function to determine whether FLASH INFO erasure is disabled. +//! +//! @return true if FLASH INFO erase is disabled, otherwise false. +// +//***************************************************************************** +bool +am_hal_flash_info_erase_disable_check(void) +{ + // + // If they are erased at this point then SRAM wipe can't be enabled. + // + if ( customer_info_signature_erased() ) + { + return false; + } + + // + // If they are not valid at this point then SRAM wipe can't be enabled. + // + if ( !am_hal_flash_customer_info_signature_check() ) + { + return false; + } + + // + // Looking good so far, now check the SRAM WIPE bit. + // + return AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & + AM_HAL_FLASH_INFO_SECURITY_ENINFOERASE_M ? false : true; +} + +//***************************************************************************** +// +//! @brief Mask off 1 to 4 quadrants of FLASH INFO space for programming. +//! +//! Use this function to set the state of the 128 valid bits at the beginning +//! of customer info space, if needed. Then and the mask bits with the INFO +//! space programming disable bits. +//! +//! @param ui32Mask - A mask of the 4 quadrants of info space where +//! bit0 = First quadrant (first 2KB). +//! bit1 = Second quadrant (second 2KB). +//! bit2 = Third quadrant (third 2KB). +//! bit3 = Fourth quadrant (fourth 2KB). +//! +//! @note This function disables only, any quadrant already disabled is not +//! reenabled. That is, any ui32Mask bits specified as 0 are essentially nops. +//! +//! @note Interrupts are active during execution of this function. Any interrupt +//! taken could cause execution errors. Please see the IMPORTANT note under +//! Detailed Description above for more details. +//! +//! @return Zero for success. Non-Zero for errors. +// +//***************************************************************************** +int32_t +am_hal_flash_info_program_disable(uint32_t ui32Mask) +{ + int iRC; + uint32_t ui32SecurityValue; + + // + // Security protection only works if the signature data is correct. + // + iRC = customer_info_signature_set(); + if ( iRC ) + { + return iRC; + } + + // + // Make sure we have a valid mask and get the mask into the correct position. + // + ui32Mask <<= AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_S; + ui32Mask &= AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_M; + + // + // The security bit set to 1 enables programming, 0 disables programming. + // + ui32SecurityValue = AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & ~ui32Mask; + + // + // Now write the word to the flash INFO space. + // + return g_am_hal_flash.flash_program_info( + AM_HAL_FLASH_PROGRAM_KEY, + 0, // instance + &ui32SecurityValue, // source data + AM_HAL_FLASH_INFO_SECURITY_O / 4, // word offset + 1 ); // number of words +} + +//***************************************************************************** +// +//! @brief Return a mask specifying which quadrants of customer INFO space have +//! been disabled for programming. +//! +//! Use this function to determine whether programming of customer INFO space +//! has been disabled. +//! +//! @return A 4-bit mask of the disabled quadrants. +//! 0xFFFFFFFF indicates an error. +//! 0x0 indicates all customer INFO space programming is enabled. +//! 0xF indicates all customer INFO space programming is disabled. +//! bit0 indicates the first customer INFO space is disabled for programming. +//! bit1 indicates the second customer INFO space is disabled for programming. +//! bit2 indicates the third customer INFO space is disabled for programming. +//! bit3 indicates the fourth customer INFO space is disabled for programming. +// +//***************************************************************************** +uint32_t +am_hal_flash_info_program_disable_get(void) +{ + // + // If they are erased at this point then SRAM wipe can't be enabled. + // + if ( customer_info_signature_erased() ) + { + return 0xFFFFFFFF; + } + + // + // If not valid at this point, then INFO programming can't be enabled. + // + if ( !am_hal_flash_customer_info_signature_check() ) + { + return 0xFFFFFFFF; + } + + // + // Looking good so far, now return a mask of the disabled bits. + // + return ((AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & + AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_M) ^ + AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_M) >> + AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_S; +} + +//***************************************************************************** +// +//! @brief Enable FLASH debugger protection (FLASH gets wiped if a debugger is +//! connected). +//! +//! Use this function to set the state of the 128 valid bits at the beginning +//! of customer info space, if needed. Then set the FLASH wipe bit to zero. +//! +//! @note Interrupts are active during execution of this function. Any interrupt +//! taken could cause execution errors. Please see the IMPORTANT note under +//! Detailed Description above for more details. +//! +//! @return Zero for success. Non-Zero for errors. +// +//***************************************************************************** +int32_t +am_hal_flash_wipe_flash_enable(void) +{ + int iRC; + uint32_t ui32SecurityValue; + + // + // Security protection only works if the signature data is correct. + // + iRC = customer_info_signature_set(); + if ( iRC ) + { + return iRC; + } + + // + // Clear the FLASH Wipe bit. + // + ui32SecurityValue = AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & + ~AM_HAL_FLASH_INFO_SECURITY_FLASHWIPE_M; + + // + // Now write the word to the flash INFO space. + // + return g_am_hal_flash.flash_program_info( + AM_HAL_FLASH_PROGRAM_KEY, + 0, // instance + &ui32SecurityValue, // source data + AM_HAL_FLASH_INFO_SECURITY_O / 4, // word offset + 1 ); // number of words +} + +//***************************************************************************** +// +//! @brief check for FLASH wipe protection enabled. +//! +//! Use this function to determine if FLASH wipe protection is enabled. +//! +//! @return true if FLASH wipe protection is enabled, otherwise false. +// +//***************************************************************************** +bool +am_hal_flash_wipe_flash_enable_check(void) +{ + // + // If they are erased at this point then flash wipe can't be enabled. + // + if ( customer_info_signature_erased() ) + { + return false; + } + + // + // If they are not valid at this point then flash wipe can't be enabled. + // + if ( !am_hal_flash_customer_info_signature_check() ) + { + return false; + } + + // + // Looking good so far, now check the Flash WIPE bit. + // + return AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & + AM_HAL_FLASH_INFO_SECURITY_FLASHWIPE_M ? false : true; +} + +//***************************************************************************** +// +//! @brief Enable SRAM protection so SRAM gets wiped if a debgger is connected. +//! +//! Use this function to set the state of the 128 valid bits at the beginning +//! of customer info space, if needed. Then set the SRAM wipe bit to zero. +//! +//! @note Interrupts are active during execution of this function. Any interrupt +//! taken could cause execution errors. Please see the IMPORTANT note under +//! Detailed Description above for more details. +//! +//! @return Zero for success. Non-Zero for errors. +// +//***************************************************************************** +int32_t +am_hal_flash_wipe_sram_enable(void) +{ + int iRC; + uint32_t ui32SecurityValue; + + // + // Security protection only works if the signature data is correct. + // + iRC = customer_info_signature_set(); + if ( iRC ) + { + return iRC; + } + + // + // Clear the SRAM Wipe bit. + // + ui32SecurityValue = AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & + ~AM_HAL_FLASH_INFO_SECURITY_SRAMWIPE_M; + + // + // Now write the word to the flash INFO space. + // + return g_am_hal_flash.flash_program_info( + AM_HAL_FLASH_PROGRAM_KEY, + 0, // instance + &ui32SecurityValue, // source data + AM_HAL_FLASH_INFO_SECURITY_O / 4, // word offset + 1 ); // number of words +} + +//***************************************************************************** +// +//! @brief check for SRAM protection enabled. +//! +//! Use this function to determine if SRAM protection is enabled. +//! +//! @return true if SRAM wipe protection is enabled, otherwise false. +// +//***************************************************************************** +bool +am_hal_flash_wipe_sram_enable_check(void) +{ + // + // If they are erased at this point then SRAM wipe can't be enabled. + // + if ( customer_info_signature_erased() ) + { + return false; + } + + // + // If they are not vale at this point then SRAM wipe can't be enabled. + // + if ( !am_hal_flash_customer_info_signature_check() ) + { + return false; + } + + // + // Looking good so far, now check the SRAM WIPE bit. + // + return AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & + AM_HAL_FLASH_INFO_SECURITY_SRAMWIPE_M ? false : true; +} + +//***************************************************************************** +// +//! @brief Disable Output from ITM/SWO. +//! +//! Use this function to set the state of the 128 valid bits at the beginning +//! of customer info space, if needed. Set the SWO disable bit to zero. +//! +//! @note Interrupts are active during execution of this function. Any interrupt +//! taken could cause execution errors. Please see the IMPORTANT note under +//! Detailed Description above for more details. +//! +//! @return Zero for success. Non-Zero for errors. +// +//***************************************************************************** +int32_t +am_hal_flash_swo_disable(void) +{ + int iRC; + uint32_t ui32SecurityValue; + + // + // Security protection only works if the signature data is correct. + // + iRC = customer_info_signature_set(); + if ( iRC ) + { + return iRC; + } + + // + // Clear the SWO bit. + // + ui32SecurityValue = AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & + ~AM_HAL_FLASH_INFO_SECURITY_SWOCTRL_M; + + // + // Now write the word to the flash INFO space. + // + return g_am_hal_flash.flash_program_info( + AM_HAL_FLASH_PROGRAM_KEY, + 0, // instance + &ui32SecurityValue, // source data + AM_HAL_FLASH_INFO_SECURITY_O / 4, // word offset + 1 ); // number of words +} + +//***************************************************************************** +// +//! @brief check for SWO disabled. +//! +//! Use this function to determine if the SWO is disabled. +//! +//! @return true if the ITM/SWO is disabled, otherwise false. +// +//***************************************************************************** +bool +am_hal_flash_swo_disable_check(void) +{ + // + // If they are erased at this point then SRAM wipe can't be enabled. + // + if ( customer_info_signature_erased() ) + { + return false; + } + + // + // If they are not vale at this point then SRAM wipe can't be enabled. + // + if ( !am_hal_flash_customer_info_signature_check() ) + { + return false; + } + + // + // Looking good so far, now check the SWO bit. + // + return AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & + AM_HAL_FLASH_INFO_SECURITY_SWOCTRL_M ? false : true; +} + +//***************************************************************************** +// +//! @brief Disable Connections from a debugger on the SWD interface. +//! +//! Use this function to set the state of the 128 valid bits at the beginning +//! of customer info space, if needed. Set the debugger disable bit to zero. +//! +//! @note Interrupts are active during execution of this function. Any interrupt +//! taken could cause execution errors. Please see the IMPORTANT note under +//! Detailed Description above for more details. +//! +//! @return Zero for success. Non-Zero for errors. +// +//***************************************************************************** +int32_t +am_hal_flash_debugger_disable(void) +{ + int iRC; + uint32_t ui32SecurityValue; + + // + // Security protection only works if the signature data is correct. + // + iRC = customer_info_signature_set(); + if ( iRC ) + { + return iRC; + } + + // + // Clear the DEBUGGER bit. + // + ui32SecurityValue = AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & + ~AM_HAL_FLASH_INFO_SECURITY_DEBUGGERPROT_M; + + // + // Now write the word to the flash INFO space. + // + return g_am_hal_flash.flash_program_info( + AM_HAL_FLASH_PROGRAM_KEY, + 0, // instance + &ui32SecurityValue, // source data + AM_HAL_FLASH_INFO_SECURITY_O / 4, // word offset + 1 ); // number of words +} + +//***************************************************************************** +// +//! @brief check for debugger disabled. +//! +//! Use this function to determine if the debugger is disabled. +//! +//! @return true if the debugger is disabled, otherwise false. +// +//***************************************************************************** +bool +am_hal_flash_debugger_disable_check(void) +{ + // + // If they are erased at this point then SRAM wipe can't be enabled. + // + if ( customer_info_signature_erased() ) + { + return false; + } + + // + // If they are not vale at this point then SRAM wipe can't be enabled. + // + if ( !am_hal_flash_customer_info_signature_check() ) + { + return false; + } + + // + // Looking good so far, now check the debugger disable bit. + // + return AM_REGVAL(AM_HAL_FLASH_INFO_SECURITY_ADDR) & + AM_HAL_FLASH_INFO_SECURITY_DEBUGGERPROT_M ? false : true; +} + +//***************************************************************************** +// +//! @brief This static helper function generates a 64-bit protection mask. +//! +//! @param pui32StartAddress - Starting address in flash to begin protection. +//! @param pui32StopAddress - Ending address in flash to stop protection. +//! +//! This function computes a chunk map for the protection range. +//! +//! @return Inverse of the actual chunk mask. That is, chunks to be protected +//! are represented as 0 in the returned mask, while chunks to be left alone +//! are represented as 1. This value can therefore be directly ANDed with the +//! existing bits in INFO space. +//! Note that -1 is returned if input parameters are invalid - this return +//! value would indicate that no chunks are to be protected. +//! +// +//***************************************************************************** +static uint64_t +generate_chunk_mask(uint32_t *pui32StartAddress, uint32_t *pui32StopAddress) +{ + uint32_t ui32ChunkStart, ui32ChunkStop; + uint32_t ui32Width; + uint64_t ui64Mask; + + // + // Validate the address input parameters + // + if ( (pui32StartAddress > pui32StopAddress) || + (pui32StopAddress > (uint32_t*)AM_HAL_FLASH_LARGEST_VALID_ADDR) ) + { + // + // Argument error, return value to leave all chunks unprotected. + // + return 0xFFFFFFFFFFFFFFFF; + } + + // + // Extract chunk related information + // + ui32ChunkStart = AM_HAL_FLASH_INFO_ADDR2CHUNK((uint32_t)pui32StartAddress); + ui32ChunkStop = AM_HAL_FLASH_INFO_ADDR2CHUNK((uint32_t)pui32StopAddress); + ui32Width = ui32ChunkStop - ui32ChunkStart + 1; + + if ( ui32Width == 64 ) + { + ui64Mask = (uint64_t)0xFFFFFFFFFFFFFFFFLLU; + } + else + { + ui64Mask = ( ((uint64_t)0x0000000000000001) << ui32Width) - 1; + ui64Mask <<= ui32ChunkStart; + } + + // + // OK now return the chunk mask (inverted). + // + return ~ui64Mask; +} + +//***************************************************************************** +// +//! @brief This function sets copy protection for a range of flash chunks. +//! +//! @param pui32StartAddress - Starting address in flash to begin protection. +//! @param pui32StopAddress - Ending address in flash to stop protection. +//! +//! This function will set copy protection bits for a range of flash chunks +//! +//! @note Each flash chunk contains 16KBytes and corresponds to one bit in +//! the protection register. Set the bit to zero to enable protection. +//! +//! @note Interrupts are active during execution of this function. Any interrupt +//! taken could cause execution errors. Please see the IMPORTANT note under +//! Detailed Description above for more details. +//! +//! @return +//! 0 for success. +//! 0x400000 if the protection bits were already programmed (mask the return +//! value with 0x3FFFFF to ignore this case and treat as success). +//! Otherwise, non-zero for failure. +// +//***************************************************************************** +int32_t +am_hal_flash_copy_protect_set(uint32_t *pui32StartAddress, + uint32_t *pui32StopAddress) +{ + int iRC; + bool bModified = false; + uint64_t ui64Mask; + uint32_t ui32Work; + uint32_t ui32Protection[2]; + uint32_t *pui32Protection = (uint32_t *)AM_HAL_FLASH_INFO_COPYPROT_ADDR; + + // + // Extract chunk mask from parameters. + // Also checks parameter validity (returns -1 if bad parameters). + // + ui64Mask = generate_chunk_mask(pui32StartAddress, pui32StopAddress); + if ( ~ui64Mask == 0x0 ) + { + return 0x100000; + } + + // + // Go get the current settings for copy protection. + // + ui32Protection[0] = pui32Protection[0]; + ui32Protection[1] = pui32Protection[1]; + + // + // AND mask off the necessary protection bits in the lower word. + // + ui32Work = (uint32_t)ui64Mask; + if ( ( ~ui32Work ) && ( ui32Work != ui32Protection[0] ) ) + { + bModified = true; + ui32Protection[0] &= ui32Work; + iRC = g_am_hal_flash.flash_program_info( + AM_HAL_FLASH_PROGRAM_KEY, + 0, // instance + &ui32Protection[0], // source data + (AM_HAL_FLASH_INFO_COPYPROT_O / 4) + 0, // word offset + 1 ); // number of words + + if ( iRC ) + { + return iRC | 0x10000; + } + } + + // + // AND mask off the necessary protection bits in the upper word. + // + ui32Work = (uint32_t)(ui64Mask >> 32); + if ( ( ~ui32Work ) && ( ui32Work != ui32Protection[1] ) ) + { + bModified = true; + ui32Protection[1] &= ui32Work; + iRC = g_am_hal_flash.flash_program_info( + AM_HAL_FLASH_PROGRAM_KEY, + 0, // instance + &ui32Protection[1], // source data + (AM_HAL_FLASH_INFO_COPYPROT_O / 4) + 1, // word offset + 1 ); // number of words + + if ( iRC ) + { + return iRC | 0x20000; + } + } + + if ( bModified ) + { + return 0; + } + else + { + return 0x400000; + } +} + +//***************************************************************************** +// +//! @brief This function checks copy protection for a range of flash chunks. +//! +//! @param pui32StartAddress - Starting address in flash. +//! @param pui32StopAddress - Ending address in flash. +//! +//! This function will check copy protection bits for a range of flash chunks +//! it expects all chunks in the range to be protected. +//! +//! @note Each flash chunk contains 16KBytes and corresponds to one bit in +//! the protection register. Set the bit to zero to enable protection. +//! +//! @return false for at least one chunk in the covered range is not protected, +//! and true if all chunks in the covered range are protected. +//! +// +//***************************************************************************** +bool +am_hal_flash_copy_protect_check(uint32_t *pui32StartAddress, + uint32_t *pui32StopAddress) +{ + uint64_t ui64Mask; + uint32_t ui32Work; + uint32_t *pui32Protection = (uint32_t *)AM_HAL_FLASH_INFO_COPYPROT_ADDR; + + // + // Extract chunk mask from parameters. + // Also checks parameter validity (returns -1 if bad parameters). + // + ui64Mask = generate_chunk_mask(pui32StartAddress, pui32StopAddress); + if ( ~ui64Mask == 0x0 ) + { + return false; + } + + // + // Now check the lower word of protection bits. + // + ui32Work = (uint32_t)ui64Mask; + if ( ~ui32Work & pui32Protection[0] ) + { + return false; + } + + // + // Now check the lower word of protection bits. + // + ui32Work = (uint32_t)(ui64Mask >> 32); + if ( ~ui32Work & pui32Protection[1] ) + { + return false; + } + + // + // If we get here, there are no unprotected chunks within specified range. + // + return true; +} + +//***************************************************************************** +// +//! @brief This function sets write protection for a range of flash chunks. +//! +//! @param pui32StartAddress - Starting address in flash to begin protection. +//! @param pui32StopAddress - Ending address in flash to stop protection. +//! +//! This function will set write protection bits for a range of flash chunks +//! +//! @note Each flash chunk contains 16KBytes and corresponds to one bit in +//! the protection register. Set the bit to zero to enable protection. +//! +//! @note Interrupts are active during execution of this function. Any interrupt +//! taken could cause execution errors. Please see the IMPORTANT note under +//! Detailed Description above for more details. +//! +//! @return +//! 0 for success. +//! 0x400000 if the protection bits were already programmed (mask the return +//! value with 0x3FFFFF to ignore this case and treat as success). +//! Otherwise, non-zero for failure. +// +//***************************************************************************** +int32_t +am_hal_flash_write_protect_set(uint32_t *pui32StartAddress, + uint32_t *pui32StopAddress) +{ + int iRC; + bool bModified = false; + uint64_t ui64Mask; + uint32_t ui32Work; + uint32_t ui32Protection[2]; + uint32_t *pui32Protection = (uint32_t *)AM_HAL_FLASH_INFO_WRITPROT_ADDR; + + // + // Extract chunk mask from parameters. + // Also checks parameter validity (returns -1 if bad parameters). + // + ui64Mask = generate_chunk_mask(pui32StartAddress, pui32StopAddress); + if ( ~ui64Mask == 0x0 ) + { + return 0x100000; + } + + // + // Go get the current settings for copy protection. + // + ui32Protection[0] = pui32Protection[0]; + ui32Protection[1] = pui32Protection[1]; + + // + // AND mask off the necessary protection bits in the lower word. + // + ui32Work = (uint32_t)ui64Mask; + if ( ( ~ui32Work ) && ( ui32Work != ui32Protection[0] ) ) + { + bModified = true; + ui32Protection[0] &= ui32Work; + iRC = g_am_hal_flash.flash_program_info( + AM_HAL_FLASH_PROGRAM_KEY, + 0, // instance + &ui32Protection[0], // source data + (AM_HAL_FLASH_INFO_WRITPROT_O / 4) + 0, // word offset + 1 ); // number of words + + if ( iRC ) + { + return iRC | 0x10000; + } + } + + // + // AND mask off the necessary protection bits in the upper word. + // + ui32Work = (uint32_t)(ui64Mask >> 32); + if ( ( ~ui32Work ) && ( ui32Work != ui32Protection[1] ) ) + { + bModified = true; + ui32Protection[1] &= ui32Work; + iRC = g_am_hal_flash.flash_program_info( + AM_HAL_FLASH_PROGRAM_KEY, + 0, // instance + &ui32Protection[1], // source data + (AM_HAL_FLASH_INFO_WRITPROT_O / 4) + 1, // word offset + 1 ); // number of words + + if ( iRC ) + { + return iRC | 0x20000; + } + } + + if ( bModified ) + { + return 0; + } + else + { + return 0x400000; + } +} + +//***************************************************************************** +// +//! @brief This function checks write protection for a range of flash chunks. +//! +//! @param pui32StartAddress - Starting address in flash. +//! @param pui32StopAddress - Ending address in flash. +//! +//! This function will check write protection bits for a range of flash chunks +//! it expects all chunks in the range to be protected. +//! +//! @note Each flash chunk contains 16KBytes and corresponds to one bit in +//! the protection register. Set the bit to zero to enable protection. +//! +//! @return false for at least one chunk in the covered range is not protected, +//! and true if all chunks in the covered range are protected. +//! +// +//***************************************************************************** +bool +am_hal_flash_write_protect_check(uint32_t *pui32StartAddress, + uint32_t *pui32StopAddress) +{ + uint64_t ui64Mask; + uint32_t ui32Work; + uint32_t *pui32Protection = (uint32_t *)AM_HAL_FLASH_INFO_WRITPROT_ADDR; + + // + // Extract chunk mask from parameters. + // Also checks parameter validity (returns -1 if bad parameters). + // + ui64Mask = generate_chunk_mask(pui32StartAddress, pui32StopAddress); + if ( ~ui64Mask == 0x0 ) + { + return false; + } + + // + // Now check the lower word of protection bits. + // + ui32Work = (uint32_t)ui64Mask; + if ( ~ui32Work & pui32Protection[0] ) + { + return false; + } + + // + // Now check the lower word of protection bits. + // + ui32Work = (uint32_t)(ui64Mask >> 32); + if ( ~ui32Work & pui32Protection[1] ) + { + return false; + } + + // + // If we get here, there are no unprotected chunks within specified range. + // + return true; +} + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_flash.h b/bsp/apollo2/libraries/drivers/hal/am_hal_flash.h new file mode 100644 index 0000000000..66d6f5059c --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_flash.h @@ -0,0 +1,297 @@ +//***************************************************************************** +// +// am_hal_flash.h +//! @file +//! +//! @brief Functions for performing Flash operations. +//! +//! @addtogroup flash2 Flash +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_FLASH_H +#define AM_HAL_FLASH_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include + +//***************************************************************************** +// +// Flash Program keys. +// +//***************************************************************************** +#define AM_HAL_FLASH_PROGRAM_KEY 0x12344321 +#define AM_HAL_FLASH_RECOVERY_KEY 0xA35C9B6D +#define AM_HAL_FLASH_INFO_KEY 0x12344321 +#define AM_HAL_FLASH_OTP_KEY (AM_HAL_FLASH_INFO_KEY) + +//***************************************************************************** +// +// Some helpful flash values and macros. +// +//***************************************************************************** +#define AM_HAL_FLASH_ADDR 0x00000000 +#define AM_HAL_FLASH_PAGE_SIZE ( 8 * 1024 ) +#define AM_HAL_FLASH_INFO_SIZE AM_HAL_FLASH_PAGE_SIZE +#define AM_HAL_FLASH_INSTANCE_SIZE ( 512 * 1024 ) +#define AM_HAL_FLASH_INSTANCE_PAGES ( AM_HAL_FLASH_INSTANCE_SIZE / AM_HAL_FLASH_PAGE_SIZE ) +#define AM_HAL_FLASH_TOTAL_SIZE ( AM_HAL_FLASH_INSTANCE_SIZE * 2 ) +#define AM_HAL_FLASH_LARGEST_VALID_ADDR ( AM_HAL_FLASH_ADDR + AM_HAL_FLASH_TOTAL_SIZE - 1 ) + +// +// Convert an absolute flash address to a instance +// +#define AM_HAL_FLASH_ADDR2INST(addr) ( ( addr >> 19 ) & 1 ) + +// +// Convert an absolute flash address to a page number relative to the instance +// +#define AM_HAL_FLASH_ADDR2PAGE(addr) ( ( addr >> 13 ) & 0x3F ) + +// +// Convert an absolute flash address to an absolute page number +// +#define AM_HAL_FLASH_ADDR2ABSPAGE(addr) ( addr >> 13 ) + +// +// Given a number of microseconds, convert to a value representing the number of +// cycles that will give that delay. This macro is basically taking into account +// some of the call overhead. +// e.g. To provide a 2us delay: +// am_hal_flash_delay( FLASH_CYCLES_US(2) ); +// +#define FLASH_CYCLES_US(n) ((n * (AM_HAL_CLKGEN_FREQ_MAX_MHZ / 3)) - 4) + +// +// Backward compatibility +// +#define am_hal_flash_program_otp am_hal_flash_program_info +#define am_hal_flash_program_otp_sram am_hal_flash_program_info_sram + +//***************************************************************************** +// +// Structure of function pointers to helper functions for invoking various +// flash operations. The functions we are pointing to here are in the Apollo 2 +// integrated BOOTROM. +// +//***************************************************************************** +typedef struct am_hal_flash_helper_struct +{ + // + // The basics. + // + int (*flash_mass_erase)(uint32_t, uint32_t); + int (*flash_page_erase)(uint32_t, uint32_t, uint32_t); + int (*flash_program_main)(uint32_t, uint32_t *, + uint32_t*, uint32_t); + int (*flash_program_info)(uint32_t, uint32_t, + uint32_t*, uint32_t, uint32_t); + + // + // Non-blocking variants, but be careful these are not interrupt safe so + // mask interrupts while these very long operations proceed. + // + int (*flash_mass_erase_nb)(uint32_t, uint32_t); + int (*flash_page_erase_nb)(uint32_t, uint32_t, uint32_t); + bool (*flash_nb_operation_complete)(void); + + // + // Essentially these are recovery options. + // + int (*flash_erase_info)(uint32_t, uint32_t); + int (*flash_erase_main_plus_info)(uint32_t, uint32_t); + int (*flash_erase_main_plus_info_both_instances)(uint32_t); + void (*flash_recovery)(uint32_t); + + // + // Useful utilities. + // + uint32_t (*flash_util_read_word)(uint32_t*); + void (*flash_util_write_word)(uint32_t*, uint32_t); + void (*delay_cycles)(uint32_t); + + // + // The following functions pointers will generally never be called from + // user programs. They are here primarily to document these entry points + // which are usable from a debugger or debugger script. + // + void (*flash_program_main_sram)(void); + void (*flash_program_info_sram)(void); + void (*flash_erase_main_pages_sram)(void); + void (*flash_mass_erase_sram)(void); + void (*flash_erase_info_sram)(void); + void (*flash_erase_main_plus_info_sram)(void); +} g_am_hal_flash_t; +extern g_am_hal_flash_t g_am_hal_flash; + + +//***************************************************************************** +// +// Define some FLASH INFO SPACE values and macros. +// +//***************************************************************************** +#define AM_HAL_FLASH_INFO_ADDR 0x50020000 +#define AM_HAL_FLASH_INFO_SECURITY_O 0x10 +#define AM_HAL_FLASH_INFO_WRITPROT_O 0x20 +#define AM_HAL_FLASH_INFO_COPYPROT_O 0x30 + +#define AM_HAL_FLASH_INFO_SECURITY_ADDR (AM_HAL_FLASH_INFO_ADDR + AM_HAL_FLASH_INFO_SECURITY_O) +#define AM_HAL_FLASH_INFO_WRITPROT_ADDR (AM_HAL_FLASH_INFO_ADDR + AM_HAL_FLASH_INFO_WRITPROT_O) +#define AM_HAL_FLASH_INFO_COPYPROT_ADDR (AM_HAL_FLASH_INFO_ADDR + AM_HAL_FLASH_INFO_COPYPROT_O) + +// +// Define the customer info signature data (at AM_HAL_FLASH_INFO_ADDR). +// These bits must exist in the customer info space in order for many of the +// security and protection functions to work. +// +#define AM_HAL_FLASH_INFO_SIGNATURE0 0x48EAAD88 +#define AM_HAL_FLASH_INFO_SIGNATURE1 0xC9705737 +#define AM_HAL_FLASH_INFO_SIGNATURE2 0x0A6B8458 +#define AM_HAL_FLASH_INFO_SIGNATURE3 0xE41A9D74 + +// +// Define the customer security bits (at AM_HAL_FLASH_INFO_SECURITY_ADDR) +// +#define AM_HAL_FLASH_INFO_SECURITY_DEBUGGERPROT_S 0 +#define AM_HAL_FLASH_INFO_SECURITY_SWOCTRL_S 1 +#define AM_HAL_FLASH_INFO_SECURITY_SRAMWIPE_S 2 +#define AM_HAL_FLASH_INFO_SECURITY_FLASHWIPE_S 3 +#define AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_S 4 +#define AM_HAL_FLASH_INFO_SECURITY_ENINFOERASE_S 8 +#define AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_S 9 + +#define AM_HAL_FLASH_INFO_SECURITY_DEBUGGERPROT_M ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_DEBUGGERPROT_S)) +#define AM_HAL_FLASH_INFO_SECURITY_SWOCTRL_M ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_SWOCTRL_S)) +#define AM_HAL_FLASH_INFO_SECURITY_SRAMWIPE_M ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_SRAMWIPE_S)) +#define AM_HAL_FLASH_INFO_SECURITY_FLASHWIPE_M ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_FLASHWIPE_S)) +#define AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_M ((uint32_t)(0xF << AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_S)) +#define AM_HAL_FLASH_INFO_SECURITY_ENINFOERASE_M ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_ENINFOERASE_S)) +#define AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_M ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_S)) +#define AM_HAL_FLASH_INFO_SECURITY_DEEPSLEEP_M ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_S)) +#define AM_HAL_FLASH_INFO_SECURITY_DEEPSLEEP ((uint32_t)(0x0 << AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_S)) + +// +// Protection chunk macros +// AM_HAL_FLASH_INFO_CHUNK2ADDR: Convert a chunk number to an address +// AM_HAL_FLASH_INFO_CHUNK2INST: Convert a chunk number to an instance number +// AM_HAL_FLASH_INFO_ADDR2CHUNK: Convert an address to a chunk number +// +#define AM_HAL_FLASH_INFO_CHUNKSIZE (16*1024) + +#define AM_HAL_FLASH_INFO_CHUNK2ADDR(n) (AM_HAL_FLASH_ADDR + (n << 14)) +#define AM_HAL_FLASH_INFO_CHUNK2INST(n) ((n >> 5) & 1 +#define AM_HAL_FLASH_INFO_ADDR2CHUNK(n) ((n) >> 14) + +//***************************************************************************** +// +// Function prototypes for the helper functions +// +//***************************************************************************** +extern int am_hal_flash_mass_erase(uint32_t ui32Value, uint32_t ui32FlashInst); +extern int am_hal_flash_page_erase(uint32_t ui32Value, uint32_t ui32FlashInst, + uint32_t ui32PageNum); +extern int am_hal_flash_program_main(uint32_t value, uint32_t *pSrc, + uint32_t *pDst, uint32_t NumberOfWords); +extern int am_hal_flash_program_info(uint32_t ui32Value, uint32_t ui32InfoInst, + uint32_t *pui32Src, uint32_t ui32Offset, + uint32_t ui32NumWords); + +// +// Recovery type functions for Customer INFO space. +// +extern int am_hal_flash_erase_info(uint32_t ui32ProgramKey, + uint32_t ui32Instance); +extern int am_hal_flash_erase_main_plus_info(uint32_t ui32ProgramKey, + uint32_t ui32Instance); +extern int am_hal_flash_erase_main_plus_info_both_instances( + uint32_t ui32ProgramKey); +extern void am_hal_flash_recovery(uint32_t ui32RecoveryKey); + +// +// BOOTROM resident reader, writer and delay utility functions. +// +extern uint32_t am_hal_flash_load_ui32(uint32_t ui32Address); +extern void am_hal_flash_store_ui32(uint32_t ui32Address, uint32_t ui32Data); +extern void am_hal_flash_delay(uint32_t ui32Iterations); + +// +// These functions update security/protection bits in the customer INFO blOCK. +// +extern bool am_hal_flash_customer_info_signature_check(void); +extern bool am_hal_flash_info_signature_set(void); +extern int32_t am_hal_flash_info_erase_disable(void); +extern bool am_hal_flash_info_erase_disable_check(void); +extern int32_t am_hal_flash_info_program_disable(uint32_t ui32Mask); +extern uint32_t am_hal_flash_info_program_disable_get(void); +extern int32_t am_hal_flash_wipe_flash_enable(void); +extern bool am_hal_flash_wipe_flash_enable_check(void); +extern int32_t am_hal_flash_wipe_sram_enable(void); +extern bool am_hal_flash_wipe_sram_enable_check(void); +extern int32_t am_hal_flash_swo_disable(void); +extern bool am_hal_flash_swo_disable_check(void); +extern int32_t am_hal_flash_debugger_disable(void); +extern bool am_hal_flash_debugger_disable_check(void); + +extern int32_t am_hal_flash_copy_protect_set(uint32_t *pui32StartAddress, + uint32_t *pui32StopAddress); +extern bool am_hal_flash_copy_protect_check(uint32_t *pui32StartAddress, + uint32_t *pui32StopAddress); +extern int32_t am_hal_flash_write_protect_set(uint32_t *pui32StartAddress, + uint32_t *pui32StopAddress); +extern bool am_hal_flash_write_protect_check(uint32_t *pui32StartAddress, + uint32_t *pui32StopAddress); + + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_FLASH_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_global.c b/bsp/apollo2/libraries/drivers/hal/am_hal_global.c new file mode 100644 index 0000000000..498eb1627a --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_global.c @@ -0,0 +1,59 @@ +//***************************************************************************** +// +// am_hal_global.c +//! @file +//! +//! @brief Locate global variables here. +//! +//! This module contains global variables that are used throughout the HAL. +//! +//! One use in particular is that it uses a global HAL flags variable that +//! contains flags used in various parts of the HAL. +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +// Global Variables +// +//***************************************************************************** +uint32_t volatile g_ui32HALflags = 0x00000000; diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_global.h b/bsp/apollo2/libraries/drivers/hal/am_hal_global.h new file mode 100644 index 0000000000..bb437b198a --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_global.h @@ -0,0 +1,114 @@ +//***************************************************************************** +// +// am_hal_global.h +//! @file +//! +//! @brief Locate all HAL global variables here. +//! +//! This module contains global variables that are used throughout the HAL, +//! but not necessarily those designated as const (which typically end up in +//! flash). Consolidating globals here will make it easier to manage them. +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_GLOBAL_H +#define AM_HAL_GLOBAL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Macro definitions +// +//***************************************************************************** + +//****************************************************************************** +// +// Macros used to access the bit fields in the flags variable. +// +//****************************************************************************** +#define AM_HAL_FLAGS_BFR(flagnm) \ + ((g_ui32HALflags & AM_HAL_FLAGS_##flagnm##_M) >> AM_HAL_FLAGS_##flagnm##_S) + +#define AM_HAL_FLAGS_BFW(flagnm, value) \ + g_ui32HALflags = ((g_ui32HALflags & (~(AM_HAL_FLAGS_##flagnm##_M))) | \ + ((value << AM_HAL_FLAGS_##flagnm##_S) & (AM_HAL_FLAGS_##flagnm##_M)) ) + +//****************************************************************************** +// +// ITMSKIPENABLEDISABLE - Set when the ITM is not to be disabled. This is +// typically needed by Keil debug.ini. +// +//****************************************************************************** +#define AM_HAL_FLAGS_ITMSKIPENABLEDISABLE_S 0 +#define AM_HAL_FLAGS_ITMSKIPENABLEDISABLE_M (1 << AM_HAL_FLAGS_ITMSKIPENABLEDISABLE_S) +#define AM_HAL_FLAGS_ITMSKIPENABLEDISABLE(n) (((n) << AM_HAL_FLAGS_ITMSKIPENABLEDISABLE_S) & AM_HAL_FLAGS_ITMSKIPENABLEDISABLE_M) + +//****************************************************************************** +// +// ITMBKPT - Breakpoint at the end of itm_enable(), which is needed by +// Keil debug.ini. +// +//****************************************************************************** +#define AM_HAL_FLAGS_ITMBKPT_S 1 +#define AM_HAL_FLAGS_ITMBKPT_M (1 << AM_HAL_FLAGS_ITMBKPT_S) +#define AM_HAL_FLAGS_ITMBKPT(n) (((n) << AM_HAL_FLAGS_ITMBKPT_S) & AM_HAL_FLAGS_ITMBKPT_M) + +//****************************************************************************** +// +// Next available flag or bit field. +// +//****************************************************************************** +#define AM_HAL_FLAGS_NEXTBITFIELD_S 2 +#define AM_HAL_FLAGS_NEXTBITFIELD_M (1 << AM_HAL_FLAGS_NEXTBITFIELD_S) +#define AM_HAL_FLAGS_NEXTBITFIELD(n) (((n) << AM_HAL_FLAGS_NEXTBITFIELD_S) & AM_HAL_FLAGS_NEXTBITFIELD_M) + +//***************************************************************************** +// +// Global Variables extern declarations. +// +//***************************************************************************** +extern volatile uint32_t g_ui32HALflags; + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_GLOBAL_H diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_gpio.c b/bsp/apollo2/libraries/drivers/hal/am_hal_gpio.c new file mode 100644 index 0000000000..480118da6b --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_gpio.c @@ -0,0 +1,503 @@ +//***************************************************************************** +// +// am_hal_gpio.c +//! @file +//! +//! @brief Functions for interfacing with the GPIO module +//! +//! @addtogroup gpio2 GPIO +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +// Array of function pointers for handling GPIO interrupts. +// +//***************************************************************************** +am_hal_gpio_handler_t am_hal_gpio_ppfnHandlers[64]; + +//***************************************************************************** +// +//! @brief Read the configuration information for the given pin.. +//! +//! @param ui32GPIONum is the GPIO number whose configuration we want to read. +//! +//! This function reads the PADREG, GPIO CFG, and ALTPAD registers for the +//! given GPIO and returns them in the following format: +//! +//! ( (ALTPAD << 16) | (CFG << 8) | PADREG) +//! +//! This is the same format used by the \e am_hal_gpio_pin_config() +//! function-like macro. +//! +//! @return Pin configuration information. +// +//***************************************************************************** +uint32_t +am_hal_gpio_pin_config_read(uint32_t ui32PinNumber) +{ + uint32_t ui32CfgVal, ui32PadregVal, ui32AltPadVal; + + am_hal_debug_assert_msg(ui32PinNumber <= 63, "Invalid GPIO number."); + + ui32CfgVal = AM_HAL_GPIO_CFG_R(ui32PinNumber); + ui32PadregVal = AM_HAL_GPIO_PADREG_R(ui32PinNumber); + ui32AltPadVal = AM_HAL_GPIO_ALTPADREG_R(ui32PinNumber); + + return ( (ui32CfgVal << CFGVAL_GPIOCFG_S) | + (ui32PadregVal << CFGVAL_PADREG_S) | + (ui32AltPadVal << CFGVAL_ALTPAD_S) ); +} + +//***************************************************************************** +// +//! @brief Get the state of ALL GPIOs from the INPUT READ REGISTER. +//! +//! This function retrieves the state of ALL GPIOs from the INPUT READ +//! REGISTER. +//! +//! @return the state for the requested GPIO or -1 for error. +// +//***************************************************************************** +uint64_t +am_hal_gpio_input_read(void) +{ + // + // Combine upper or lower GPIO words into one 64 bit return value. + // + uint64_t ui64RetVal; + + ui64RetVal = ((uint64_t) AM_REGn(GPIO, 0, RDB)) << 32; + ui64RetVal |= ((uint64_t) AM_REGn(GPIO, 0, RDA)) << 0; + + return ui64RetVal; +} + +//***************************************************************************** +// +//! @brief Get the state of ALL GPIOs from the DATA OUTPUT REGISTER. +//! +//! This function retrieves the state of ALL GPIOs from the DATA OUTPUT +//! REGISTER. +//! +//! @return the state for the requested GPIO or -1 for error. +// +//***************************************************************************** +uint64_t +am_hal_gpio_out_read(void) +{ + // + // Combine upper or lower GPIO words into one 64 bit return value. + // + uint64_t ui64RetVal; + + ui64RetVal = ((uint64_t) AM_REGn(GPIO, 0, WTB)) << 32; + ui64RetVal |= ((uint64_t) AM_REGn(GPIO, 0, WTA)) << 0; + + return ui64RetVal; +} + +//***************************************************************************** +// +//! @brief Gets the state of one GPIO from the DATA ENABLE REGISTER. +//! +//! @param ui32BitNum - GPIO number. +//! +//! This function gets the state of one GPIO from the DATA ENABLE REGISTER. +//! +//! @return the current state for the requested GPIO. +// +//***************************************************************************** +uint32_t +am_hal_gpio_out_enable_bit_get(uint32_t ui32BitNum) +{ + // + // Return 0 or 1. + // + + return (AM_HAL_GPIO_EN(ui32BitNum) & AM_HAL_GPIO_EN_M(ui32BitNum)) ? 1 : 0; +} + +//***************************************************************************** +// +//! @brief Gets the state of ALL GPIOs from the DATA ENABLE REGISTER. +//! +//! @param ui32BitNum - GPIO number. +//! +//! This function gets the state of all GPIOs from the DATA ENABLE REGISTER. +//! +//! @return the current state for the ALL GPIOs. +// +//***************************************************************************** +uint64_t +am_hal_gpio_out_enable_get(void) +{ + // + // Combine upper or lower GPIO words into one 64 bit return value. + // + uint64_t ui64RetVal; + + ui64RetVal = ((uint64_t) AM_REGn(GPIO, 0, ENB)) << 32; + ui64RetVal |= ((uint64_t) AM_REGn(GPIO, 0, ENA)) << 0; + + return ui64RetVal; +} + +//***************************************************************************** +// +//! @brief Enable selected GPIO Interrupts. +//! +//! @param ui64InterruptMask - GPIOs to enable interrupts on. +//! +//! Use this function to enable the GPIO interrupts. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_gpio_int_enable(uint64_t ui64InterruptMask) +{ + // + // Enable the interrupts. + // + AM_REG(GPIO, INT1EN) |= (ui64InterruptMask >> 32); + AM_REG(GPIO, INT0EN) |= (ui64InterruptMask & 0xFFFFFFFF); +} + +//***************************************************************************** +// +//! @brief Enable selected GPIO Interrupts. +//! +//! Use this function to enable the GPIO interrupts. +//! +//! @return logical or of all enabled interrupts. Use AM_HAL_GPIO_BITx to mask +//! interrupts of interest. +// +//***************************************************************************** +uint64_t +am_hal_gpio_int_enable_get(void) +{ + // + // Return enabled interrupts. + // + uint64_t ui64RetVal; + + ui64RetVal = ((uint64_t) AM_REGn(GPIO, 0, INT1EN)) << 32; + ui64RetVal |= ((uint64_t) AM_REGn(GPIO, 0, INT0EN)) << 0; + + return ui64RetVal; +} + +//***************************************************************************** +// +//! @brief Disable selected GPIO Interrupts. +//! +//! @param ui64InterruptMask - GPIOs to disable interrupts on. +//! +//! Use this function to disable the GPIO interrupts. +//! +//! ui64InterruptMask should be a logical or of AM_HAL_GPIO_BITx defines. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_gpio_int_disable(uint64_t ui64InterruptMask) +{ + // + // Disable the interrupts. + // + AM_CRITICAL_BEGIN_ASM + AM_REG(GPIO, INT1EN) &= ~(ui64InterruptMask >> 32); + AM_REG(GPIO, INT0EN) &= ~(ui64InterruptMask & 0xFFFFFFFF); + AM_CRITICAL_END_ASM +} + +//***************************************************************************** +// +//! @brief Clear selected GPIO Interrupts. +//! +//! @param ui64InterruptMask - GPIOs to clear interrupts on. +//! +//! Use this function to clear the GPIO interrupts. +//! +//! ui64InterruptMask should be a logical or of AM_HAL_GPIO_BITx defines. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_gpio_int_clear(uint64_t ui64InterruptMask) +{ + // + // Clear the interrupts. + // + AM_CRITICAL_BEGIN_ASM + AM_REG(GPIO, INT1CLR) = (ui64InterruptMask >> 32); + AM_REG(GPIO, INT0CLR) = (ui64InterruptMask & 0xFFFFFFFF); + AM_CRITICAL_END_ASM +} + +//***************************************************************************** +// +//! @brief Set selected GPIO Interrupts. +//! +//! @param ui64InterruptMask - GPIOs to set interrupts on. +//! +//! Use this function to set the GPIO interrupts. +//! +//! ui64InterruptMask should be a logical or of AM_HAL_GPIO_BITx defines. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_gpio_int_set(uint64_t ui64InterruptMask) +{ + // + // Set the interrupts. + // + AM_REG(GPIO, INT1SET) = (ui64InterruptMask >> 32); + AM_REG(GPIO, INT0SET) = (ui64InterruptMask & 0xFFFFFFFF); +} + +//***************************************************************************** +// +//! @brief Set selected GPIO Interrupts. +//! +//! @param bEnabledOnly - return the status of only the enabled interrupts. +//! +//! Use this function to set the GPIO interrupts. +//! +//! @return None +// +//***************************************************************************** +uint64_t +am_hal_gpio_int_status_get(bool bEnabledOnly) +{ + uint64_t ui64RetVal, ui64Mask; + + // + // Combine upper or lower GPIO words into one 64 bit return value. + // + ui64Mask = 0xFFFFFFFFFFFFFFFF; + + AM_CRITICAL_BEGIN_ASM + ui64RetVal = ((uint64_t) AM_REGn(GPIO, 0, INT1STAT)) << 32; + ui64RetVal |= ((uint64_t) AM_REGn(GPIO, 0, INT0STAT)) << 0; + + if ( bEnabledOnly ) + { + ui64Mask = ((uint64_t) AM_REGn(GPIO, 0, INT1EN)) << 32; + ui64Mask |= ((uint64_t) AM_REGn(GPIO, 0, INT0EN)) << 0; + } + + ui64RetVal &= ui64Mask; + AM_CRITICAL_END_ASM + + return ui64RetVal; +} + +//***************************************************************************** +// +//! @brief Convenience function for responding to pin interrupts. +//! +//! @param ui64Status is the interrupt status as returned by +//! am_hal_gpio_int_status_get() +//! +//! This function may be called from am_hal_gpio_isr() to read the status of +//! the GPIO interrupts, determine which pin(s) caused the most recent +//! interrupt, and call an interrupt handler function to respond. The interrupt +//! handler to be called must be first registered with the +//! am_hal_gpio_int_register() function. +//! +//! In the event that multiple GPIO interrupts are active, the corresponding +//! interrupt handlers will be called in numerical order by GPIO number +//! starting with the lowest GPIO number. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_gpio_int_service(uint64_t ui64Status) +{ + uint32_t ui32Status; + uint32_t ui32Clz; + + am_hal_gpio_handler_t pfnHandler; + + // + // Handle any active interrupts in the lower 32 bits + // + ui32Status = (uint32_t) ui64Status; + while ( ui32Status ) + { + // + // Pick one of any remaining active interrupt bits + // +#ifdef __IAR_SYSTEMS_ICC__ + ui32Clz = __CLZ(ui32Status); +#else + ui32Clz = __builtin_clz(ui32Status); +#endif + + // + // Turn off the bit we picked in the working copy + // + ui32Status &= ~(0x80000000 >> ui32Clz); + + // + // Check the bit handler table to see if there is an interrupt handler + // registered for this particular bit. + // + pfnHandler = am_hal_gpio_ppfnHandlers[31 - ui32Clz]; + if ( pfnHandler ) + { + // + // If we found an interrupt handler routine, call it now. + // + pfnHandler(); + } + } + + // + // Handle any active interrupts in the upper 32 bits + // + ui32Status = (uint32_t) (ui64Status >> 32); + while ( ui32Status ) + { + // + // Pick one of any remaining active interrupt bits + // +#ifdef __IAR_SYSTEMS_ICC__ + ui32Clz = __CLZ(ui32Status); +#else + ui32Clz = __builtin_clz(ui32Status); +#endif + + // + // Turn off the bit we picked in the working copy + // + ui32Status &= ~(0x80000000 >> ui32Clz); + + // + // Check the bit handler table to see if there is an interrupt handler + // registered for this particular bit. + // + pfnHandler = am_hal_gpio_ppfnHandlers[63 - ui32Clz]; + if ( pfnHandler ) + { + // + // If we found an interrupt handler routine, call it now. + // + pfnHandler(); + } + } +} + +//***************************************************************************** +// +//! @brief Register an interrupt handler for an individual GPIO pin. +//! +//! @param ui32GPIONumber - GPIO number to assign this interrupt handler to. +//! @param pfnHandler - Function to call when this GPIO interrupt is received. +//! +//! This function allows the caller to specify a function that should be called +//! any time a GPIO interrupt is received on a particular pin. Registering an +//! interrupt handler using this function adds the function pointer to an array +//! in SRAM. This interrupt handler will be called by am_hal_gpio_int_service() +//! whenever the ui64Status parameter indicates that the corresponding pin is +//! asserting it's interrupt. +//! +//! To remove an interrupt handler that has already been registered, the +//! pfnHandler parameter may be set to zero. +//! +//! @note This function will not have any effect unless the +//! am_hal_gpio_int_service() function is being used. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_gpio_int_register(uint32_t ui32GPIONumber, + am_hal_gpio_handler_t pfnHandler) +{ + // + // Check to make sure the GPIO number is valid. (Debug builds only) + // + am_hal_debug_assert_msg(ui32GPIONumber < 64, "GPIO number out of range."); + + am_hal_gpio_ppfnHandlers[ui32GPIONumber] = pfnHandler; +} + +//***************************************************************************** +// +//! @brief Get the state of one GPIO polarity bit. +//! +//! @param ui32BitNum - GPIO number. +//! +//! This function gets the state of one GPIO polarity bit. +//! +//! @note When the bit is a one the interrupt polarity is rising edge. +//! +//! @return the current polarity. +// +//***************************************************************************** +bool +am_hal_gpio_int_polarity_bit_get(uint32_t ui32BitNum) +{ + // + // Check the GPIO_CFGx register's interrupt polarity bit corresponding to + // this pin number. + // + return (AM_REGVAL(AM_HAL_GPIO_CFG(ui32BitNum)) & + AM_HAL_GPIO_POL_M(ui32BitNum)); +} + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_gpio.h b/bsp/apollo2/libraries/drivers/hal/am_hal_gpio.h new file mode 100644 index 0000000000..60e5cf36d6 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_gpio.h @@ -0,0 +1,684 @@ +//***************************************************************************** +// +// am_hal_gpio.h +//! @file +//! +//! @brief Functions for accessing and configuring the GPIO module. +//! +//! @addtogroup gpio2 GPIO +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#ifndef AM_HAL_GPIO_H +#define AM_HAL_GPIO_H + +// DEVICE ADDRESS IS 8-bits +#define AM_HAL_GPIO_DEV_ADDR_8 (0) + +// DEVICE ADDRESS IS 16-bits +#define AM_HAL_GPIO_DEV_ADDR_16 (1) + +// DEVICE OFFSET IS 8-bits +#define AM_HAL_GPIO_DEV_OFFSET_8 (0x00000000) + +// DEVICE OFFSET IS 16-bits +#define AM_HAL_GPIO_DEV_OFFSET_16 (0x00010000) + +// Maximum number of GPIOs on this device +#define AM_HAL_GPIO_MAX_PADS (50) + +//***************************************************************************** +// +//! @name GPIO Pin defines +//! @brief GPIO Pin defines for use with interrupt functions +//! +//! These macros may be used to with \e am_hal_gpio_int_x(). +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_GPIO_BIT(n) (((uint64_t) 0x1) << n) +//! @} + +// +// Helper macros used for unraveling the GPIO configuration value (configval). +// +// Note that the configval, which is passed into functions such as +// am_hal_gpio_pin_config() as well as various helper macros, is a concatenated +// value that contains values used in multiple configuration registers. +// +// The GPIO configuration value fields are arranged as follows: +// [ 7: 0] PADREG configuration. +// [11: 8] GPIOCFG +// [15:12] Unused. +// [23:16] ALTPADREG configuration. +// +// Define macros describing these configval fields. +// +#define CFGVAL_PADREG_S 0 +#define CFGVAL_PADREG_M (0xFF << CFGVAL_PADREG_S) +#define CFGVAL_GPIOCFG_S 8 +#define CFGVAL_GPIOCFG_M (0x0F << CFGVAL_GPIOCFG_S) +#define CFGVAL_ALTPAD_S 16 +#define CFGVAL_ALTPAD_M (0xFF << CFGVAL_ALTPAD_S) + +// +// Extraction macros +// +#define CFGVAL_PADREG_X(x) (((uint32_t)(x) & CFGVAL_PADREG_M) >> \ + CFGVAL_PADREG_S) +#define CFGVAL_GPIOCFG_X(x) (((uint32_t)(x) & CFGVAL_GPIOCFG_M) >> \ + CFGVAL_GPIOCFG_S) +#define CFGVAL_ALTPAD_X(x) (((uint32_t)(x) & CFGVAL_ALTPAD_M) >> \ + CFGVAL_ALTPAD_S) + +//***************************************************************************** +// +// Input options. +// +//***************************************************************************** +#define AM_HAL_GPIO_INPEN (0x02 << CFGVAL_PADREG_S) // Enable input transistors. +#define AM_HAL_GPIO_INCFG_RDZERO (0x01 << CFGVAL_GPIOCFG_S) // Disable input read registers. + +//***************************************************************************** +// +// Output options +// +//***************************************************************************** +#define AM_HAL_GPIO_OUT_DISABLE ((0x0 << 1) << CFGVAL_GPIOCFG_S) +#define AM_HAL_GPIO_OUT_PUSHPULL ((0x1 << 1) << CFGVAL_GPIOCFG_S) +#define AM_HAL_GPIO_OUT_OPENDRAIN ((0x2 << 1) << CFGVAL_GPIOCFG_S) +#define AM_HAL_GPIO_OUT_3STATE ((0x3 << 1) << CFGVAL_GPIOCFG_S) + +//***************************************************************************** +// +// Pad configuration options. +// (Configuration value bits 7:0.) +// +//***************************************************************************** +#define AM_HAL_GPIO_HIGH_DRIVE (0x04 << CFGVAL_PADREG_S) +#define AM_HAL_GPIO_LOW_DRIVE (0x00 << CFGVAL_PADREG_S) +#define AM_HAL_GPIO_PULLUP (0x01 << CFGVAL_PADREG_S) +#define AM_HAL_GPIO_PULL1_5K ( (0x01 << CFGVAL_PADREG_S) | \ + AM_HAL_GPIO_PULLUP ) +#define AM_HAL_GPIO_PULL6K ( (0x40 << CFGVAL_PADREG_S) | \ + AM_HAL_GPIO_PULLUP ) +#define AM_HAL_GPIO_PULL12K ( (0x80 << CFGVAL_PADREG_S) | \ + AM_HAL_GPIO_PULLUP ) +#define AM_HAL_GPIO_PULL24K ( (0xC0 << CFGVAL_PADREG_S) | \ + AM_HAL_GPIO_PULLUP ) + +// POWER SWITCH is available on selected pins +#define AM_HAL_GPIO_POWER (0x80 << CFGVAL_PADREG_S) + +//***************************************************************************** +// +//! ALTPADREG configuration options. +//! (Configuration value bits 23:16.) +//! +//! All Apollo2 GPIO pins can be configured for 2mA or 4mA. +//! AM_HAL_GPIO_DRIVE_2MA = 2mA configuration. +//! AM_HAL_GPIO_DRIVE_4MA = 4mA configuration. +//! +//! Certain Apollo2 GPIO pins can be configured to drive up to 12mA. +//! AM_HAL_GPIO_DRIVE_8MA = 8mA configuration. +//! AM_HAL_GPIO_DRIVE_12MA = 12mA configuration. +//! +//! Notes: +//! - Always consult the Apollo2 data sheet for the latest details. +//! - The higher drive GPIOxx pads generally include: +//! 0-2,5,7-8,10,12-13,22-23,26-29,38-39,42,44-48. +//! - GPIOxx pads that do not support the higher drive: +//! 3-4,6,9,11,14-21,24-25,30-37,40-41,43,49. +//! - User is responsible for ensuring that the selected pin actually supports +//! the higher drive (8mA or 12mA) capabilities. See the Apollo2 data sheet. +//! - Attempting to set the higher drive (8mA or 12mA) configuration on a +//! non-supporting pad will actually set the pad for 4mA drive strength, +//! regardless of the lower bit setting. +// +//***************************************************************************** +#define AM_HAL_GPIO_DRIVE_2MA ( 0 ) +#define AM_HAL_GPIO_DRIVE_4MA AM_HAL_GPIO_HIGH_DRIVE +#define AM_HAL_GPIO_DRIVE_8MA ( 0x01 << CFGVAL_ALTPAD_S ) +#define AM_HAL_GPIO_DRIVE_12MA ( (0x01 << CFGVAL_ALTPAD_S) | \ + AM_HAL_GPIO_HIGH_DRIVE ) + +#define AM_HAL_GPIO_SLEWRATE ( 0x10 << CFGVAL_ALTPAD_S ) + +//***************************************************************************** +// +// Interrupt polarity +// These values can be used directly in the configval. +// +//***************************************************************************** +#define AM_HAL_GPIOCFGVAL_FALLING ((1 << 2) << CFGVAL_GPIOCFG_S) +#define AM_HAL_GPIOCFGVAL_RISING ((0 << 2) << CFGVAL_GPIOCFG_S) + +//***************************************************************************** +// +// Pad function select +// This macro represents the 3 bit function select field in the PADREG byte. +// +//***************************************************************************** +#define AM_HAL_GPIO_FUNC(x) ((x & 0x7) << 3) + +//***************************************************************************** +// +//! Interrupt polarity +//! +//! Important: +//! These values are to be used with am_hal_gpio_int_polarity_bit_set(). +// They are not intended to be used as part of the GPIO configval. +// +//***************************************************************************** +#define AM_HAL_GPIO_FALLING 0x00000001 +#define AM_HAL_GPIO_RISING 0x00000000 + +//***************************************************************************** +// +// A few common pin configurations. +// +//***************************************************************************** +#define AM_HAL_GPIO_DISABLE \ + (AM_HAL_GPIO_FUNC(3)) + +#define AM_HAL_GPIO_INPUT \ + (AM_HAL_GPIO_FUNC(3) | AM_HAL_GPIO_INPEN) + +#define AM_HAL_GPIO_OUTPUT \ + (AM_HAL_GPIO_FUNC(3) | AM_HAL_GPIO_OUT_PUSHPULL) + +#define AM_HAL_GPIO_OPENDRAIN \ + (AM_HAL_GPIO_FUNC(3) | AM_HAL_GPIO_OUT_OPENDRAIN | AM_HAL_GPIO_INPEN) + +#define AM_HAL_GPIO_3STATE \ + (AM_HAL_GPIO_FUNC(3) | AM_HAL_GPIO_OUT_3STATE) + +//***************************************************************************** +// +// PADREG helper macros. +// +//***************************************************************************** +#define AM_HAL_GPIO_PADREG(n) \ + (AM_REG_GPIOn(0) + AM_REG_GPIO_PADREGA_O + (n & 0xFC)) + +#define AM_HAL_GPIO_PADREG_S(n) \ + (((uint32_t)(n) % 4) << 3) + +#define AM_HAL_GPIO_PADREG_M(n) \ + ((uint32_t) 0xFF << AM_HAL_GPIO_PADREG_S(n)) + +#define AM_HAL_GPIO_PADREG_FIELD(n, configval) \ + (((uint32_t)(configval) & CFGVAL_PADREG_M) << AM_HAL_GPIO_PADREG_S(n)) + +#define AM_HAL_GPIO_PADREG_W(n, configval) \ + AM_REGVAL(AM_HAL_GPIO_PADREG(n)) = \ + (AM_HAL_GPIO_PADREG_FIELD(n, configval) | \ + (AM_REGVAL(AM_HAL_GPIO_PADREG(n)) & ~AM_HAL_GPIO_PADREG_M(n))) + +#define AM_HAL_GPIO_PADREG_R(n) \ + ((AM_REGVAL(AM_HAL_GPIO_PADREG(n)) & AM_HAL_GPIO_PADREG_M(n)) >> \ + AM_HAL_GPIO_PADREG_S(n)) + + +//***************************************************************************** +// +// ALTPADCFG helper macros. +// The ALTPADCFG bits are located in [23:16] of the configval. +// +//***************************************************************************** +#define AM_HAL_GPIO_ALTPADREG(n) \ + (AM_REG_GPIOn(0) + AM_REG_GPIO_ALTPADCFGA_O + (n & 0xFC)) + +#define AM_HAL_GPIO_ALTPADREG_S(n) \ + (((uint32_t)(n) % 4) << 3) + +#define AM_HAL_GPIO_ALTPADREG_M(n) \ + ((uint32_t) 0xFF << AM_HAL_GPIO_ALTPADREG_S(n)) + +#define AM_HAL_GPIO_ALTPADREG_FIELD(n, configval) \ + (CFGVAL_ALTPAD_X(configval) << AM_HAL_GPIO_ALTPADREG_S(n)) + +#define AM_HAL_GPIO_ALTPADREG_W(n, configval) \ + AM_REGVAL(AM_HAL_GPIO_ALTPADREG(n)) = \ + (AM_HAL_GPIO_ALTPADREG_FIELD(n, configval) | \ + (AM_REGVAL(AM_HAL_GPIO_ALTPADREG(n)) & ~AM_HAL_GPIO_ALTPADREG_M(n))) + +#define AM_HAL_GPIO_ALTPADREG_R(n) \ + ((AM_REGVAL(AM_HAL_GPIO_ALTPADREG(n)) & AM_HAL_GPIO_ALTPADREG_M(n)) >> \ + AM_HAL_GPIO_ALTPADREG_S(n)) + +//***************************************************************************** +// +// CFG helper macros. +// +//***************************************************************************** +#define AM_HAL_GPIO_CFG(n) \ + (AM_REG_GPIOn(0) + AM_REG_GPIO_CFGA_O + ((n & 0xF8) >> 1)) + +#define AM_HAL_GPIO_CFG_S(n) \ + (((uint32_t)(n) % 8) << 2) + +#define AM_HAL_GPIO_CFG_M(n) \ + ((uint32_t) 0x7 << AM_HAL_GPIO_CFG_S(n)) + +#define AM_HAL_GPIO_CFG_FIELD(n, configval) \ + ((((uint32_t)(configval) & 0x700) >> 8) << AM_HAL_GPIO_CFG_S(n)) + +#define AM_HAL_GPIO_CFG_W(n, configval) \ + AM_REGVAL(AM_HAL_GPIO_CFG(n)) = \ + (AM_HAL_GPIO_CFG_FIELD(n, configval) | \ + (AM_REGVAL(AM_HAL_GPIO_CFG(n)) & ~AM_HAL_GPIO_CFG_M(n))) + +#define AM_HAL_GPIO_CFG_R(n) \ + ((AM_REGVAL(AM_HAL_GPIO_CFG(n)) & AM_HAL_GPIO_CFG_M(n)) >> \ + AM_HAL_GPIO_CFG_S(n)) + +//***************************************************************************** +// +// Polarity helper macros. +// +//***************************************************************************** +#define AM_HAL_GPIO_POL_S(n) \ + ((((uint32_t)(n) % 8) << 2) + 3) + +#define AM_HAL_GPIO_POL_M(n) \ + ((uint32_t) 0x1 << AM_HAL_GPIO_POL_S(n)) + +#define AM_HAL_GPIO_POL_FIELD(n, polarity) \ + (((uint32_t)(polarity) & 0x1) << AM_HAL_GPIO_POL_S(n)) + +#define AM_HAL_GPIO_POL_W(n, polarity) \ + AM_REGVAL(AM_HAL_GPIO_CFG(n)) = \ + (AM_HAL_GPIO_POL_FIELD(n, polarity) | \ + (AM_REGVAL(AM_HAL_GPIO_CFG(n)) & ~AM_HAL_GPIO_POL_M(n))) + +//***************************************************************************** +// +// RD helper macros. +// +//***************************************************************************** +#define AM_HAL_GPIO_RD_REG(n) \ + (AM_REG_GPIOn(0) + AM_REG_GPIO_RDA_O + (((uint32_t)(n) & 0x20) >> 3)) + +#define AM_HAL_GPIO_RD_S(n) \ + ((uint32_t)(n) % 32) + +#define AM_HAL_GPIO_RD_M(n) \ + ((uint32_t) 0x1 << AM_HAL_GPIO_RD_S(n)) + +#define AM_HAL_GPIO_RD(n) \ + AM_REGVAL(AM_HAL_GPIO_RD_REG(n)) + +//***************************************************************************** +// +// WT helper macros. +// +//***************************************************************************** +#define AM_HAL_GPIO_WT_REG(n) \ + (AM_REG_GPIOn(0) + AM_REG_GPIO_WTA_O + (((uint32_t)(n) & 0x20) >> 3)) + +#define AM_HAL_GPIO_WT_S(n) \ + ((uint32_t)(n) % 32) + +#define AM_HAL_GPIO_WT_M(n) \ + ((uint32_t) 0x1 << AM_HAL_GPIO_WT_S(n)) + +#define AM_HAL_GPIO_WT(n) \ + AM_REGVAL(AM_HAL_GPIO_WT_REG(n)) + +//***************************************************************************** +// +// WTS helper macros. +// +//***************************************************************************** +#define AM_HAL_GPIO_WTS_REG(n) \ + (AM_REG_GPIOn(0) + AM_REG_GPIO_WTSA_O + (((uint32_t)(n) & 0x20) >> 3)) + +#define AM_HAL_GPIO_WTS_S(n) \ + ((uint32_t)(n) % 32) + +#define AM_HAL_GPIO_WTS_M(n) \ + ((uint32_t) 0x1 << AM_HAL_GPIO_WTS_S(n)) + +#define AM_HAL_GPIO_WTS(n) \ + AM_REGVAL(AM_HAL_GPIO_WTS_REG(n)) + +//***************************************************************************** +// +// WTC helper macros. +// +//***************************************************************************** +#define AM_HAL_GPIO_WTC_REG(n) \ + (AM_REG_GPIOn(0) + AM_REG_GPIO_WTCA_O + (((uint32_t)(n) & 0x20) >> 3)) + +#define AM_HAL_GPIO_WTC_S(n) \ + ((uint32_t)(n) % 32) + +#define AM_HAL_GPIO_WTC_M(n) \ + ((uint32_t) 0x1 << AM_HAL_GPIO_WTC_S(n)) + +#define AM_HAL_GPIO_WTC(n) \ + AM_REGVAL(AM_HAL_GPIO_WTC_REG(n)) + +//***************************************************************************** +// +// EN helper macros. +// +//***************************************************************************** +#define AM_HAL_GPIO_EN_REG(n) \ + (AM_REG_GPIOn(0) + AM_REG_GPIO_ENA_O + (((uint32_t)(n) & 0x20) >> 3)) + +#define AM_HAL_GPIO_EN_S(n) \ + ((uint32_t)(n) % 32) + +#define AM_HAL_GPIO_EN_M(n) \ + ((uint32_t) 0x1 << AM_HAL_GPIO_EN_S(n)) + +#define AM_HAL_GPIO_EN(n) \ + AM_REGVAL(AM_HAL_GPIO_EN_REG(n)) + +//***************************************************************************** +// +// ENS helper macros. +// +//***************************************************************************** +#define AM_HAL_GPIO_ENS_REG(n) \ + (AM_REG_GPIOn(0) + AM_REG_GPIO_ENSA_O + (((uint32_t)(n) & 0x20) >> 3)) + +#define AM_HAL_GPIO_ENS_S(n) \ + ((uint32_t)(n) % 32) + +#define AM_HAL_GPIO_ENS_M(n) \ + ((uint32_t) 0x1 << AM_HAL_GPIO_ENS_S(n)) + +#define AM_HAL_GPIO_ENS(n) \ + AM_REGVAL(AM_HAL_GPIO_ENS_REG(n)) + +//***************************************************************************** +// +// ENC helper macros. +// +//***************************************************************************** +#define AM_HAL_GPIO_ENC_REG(n) \ + (AM_REG_GPIOn(0) + AM_REG_GPIO_ENCA_O + (((uint32_t)(n) & 0x20) >> 3)) + +#define AM_HAL_GPIO_ENC_S(n) \ + ((uint32_t)(n) % 32) + +#define AM_HAL_GPIO_ENC_M(n) \ + ((uint32_t) 0x1 << AM_HAL_GPIO_ENC_S(n)) + +#define AM_HAL_GPIO_ENC(n) \ + AM_REGVAL(AM_HAL_GPIO_ENC_REG(n)) + +//***************************************************************************** +// +//! @brief Configure the GPIO PAD MUX & GPIO PIN Configurations +//! +//! @param ui32PinNumber - GPIO pin number. +//! @param ui32Config - Configuration options. +//! +//! This function applies the settings for a single GPIO. For a list of valid +//! options please see the top of this file (am_hal_gpio.h) and am_hal_pin.h. +//! +//! Usage examples: +//! am_hal_gpio_pin_config(11, AM_HAL_GPIO_INPUT); +//! am_hal_gpio_pin_config(10, AM_HAL_GPIO_OUTPUT); +//! am_hal_gpio_pin_config(14, AM_HAL_GPIO_OUTPUT | AM_HAL_GPIO_SLEWRATE); +//! am_hal_gpio_pin_config(15, AM_HAL_GPIO_OUTPUT | AM_HAL_GPIO_HIGHDRIVESTR); +// +//***************************************************************************** +#define am_hal_gpio_pin_config(ui32PinNumber, ui32Config) \ + if ( (uint32_t)(ui32PinNumber) < AM_HAL_GPIO_MAX_PADS ) \ + { \ + AM_CRITICAL_BEGIN_ASM \ + \ + AM_REGn(GPIO, 0, PADKEY) = AM_REG_GPIO_PADKEY_KEYVAL; \ + \ + AM_HAL_GPIO_CFG_W(ui32PinNumber, ui32Config); \ + AM_HAL_GPIO_PADREG_W(ui32PinNumber, ui32Config); \ + AM_HAL_GPIO_ALTPADREG_W(ui32PinNumber, ui32Config); \ + \ + AM_REGn(GPIO, 0, PADKEY) = 0; \ + \ + AM_CRITICAL_END_ASM \ + } + +//***************************************************************************** +// +//! @brief Set the state of one GPIO polarity bit. +//! +//! @param ui32BitNum - GPIO number. +//! @param ui32Polarity - Desired state. +//! +//! This function sets the state of one GPIO polarity bit to a supplied value. +//! The ui32Polarity parameter should be one of the following values: +//! +//! AM_HAL_GPIO_FALLING +//! AM_HAL_GPIO_RISING +//! +//! @return None. +// +//***************************************************************************** +#define am_hal_gpio_int_polarity_bit_set(ui32PinNumber, ui32Polarity) \ + if ( (uint32_t)(ui32PinNumber) < AM_HAL_GPIO_MAX_PADS ) \ + { \ + AM_CRITICAL_BEGIN_ASM \ + \ + AM_REGn(GPIO, 0, PADKEY) = AM_REG_GPIO_PADKEY_KEYVAL; \ + AM_HAL_GPIO_POL_W(ui32PinNumber, ui32Polarity); \ + AM_REGn(GPIO, 0, PADKEY) = 0; \ + \ + AM_CRITICAL_END_ASM \ + } + +//***************************************************************************** +// +//! @brief Get the state of one GPIO from the INPUT READ REGISTER. +//! +//! @param ui32BitNum - GPIO number. +//! +//! This function retrieves the state of one GPIO from the INPUT READ +//! REGISTER. +//! +//! @return the state for the requested GPIO. +// +//***************************************************************************** +#define am_hal_gpio_input_bit_read(ui32BitNum) \ + ((AM_HAL_GPIO_RD(ui32BitNum) & AM_HAL_GPIO_RD_M(ui32BitNum)) != 0) + +//***************************************************************************** +// +//! @brief Get the state of one GPIO in the DATA OUTPUT REGISTER +//! +//! @param ui32BitNum - GPIO number. +//! +//! This function retrieves the state of one GPIO in the DATA OUTPUT REGISTER. +//! +//! @return the state for the requested GPIO or -1 for error. +// +//***************************************************************************** +#define am_hal_gpio_out_bit_read(ui32BitNum) \ + ((AM_HAL_GPIO_WT(ui32BitNum) & AM_HAL_GPIO_WT_M(ui32BitNum)) != 0) + +//***************************************************************************** +// +//! @brief Set the output state high for one GPIO. +//! +//! @param ui32BitNum - GPIO number. +//! +//! This function sets the output state to high for one GPIO. +//! +//! @return None. +// +//***************************************************************************** +#define am_hal_gpio_out_bit_set(ui32BitNum) \ + AM_HAL_GPIO_WTS(ui32BitNum) = AM_HAL_GPIO_WTS_M(ui32BitNum) + +//***************************************************************************** +// +//! @brief Sets the output state to low for one GPIO. +//! +//! @param ui32BitNum - GPIO number. +//! +//! This function sets the output state to low for one GPIO. +//! +//! @return None. +// +//***************************************************************************** +#define am_hal_gpio_out_bit_clear(ui32BitNum) \ + AM_HAL_GPIO_WTC(ui32BitNum) = AM_HAL_GPIO_WTC_M(ui32BitNum) + +//***************************************************************************** +// +//! @brief Sets the output state to ui32Value for one GPIO. +//! +//! @param ui32BitNum - GPIO number. +//! @param ui32Value - Desired output state. +//! +//! This function sets the output state to ui32Value for one GPIO. +//! +//! @return None. +// +//***************************************************************************** +#define am_hal_gpio_out_bit_replace(ui32BitNum, ui32Value) \ + if ( ui32Value ) \ + { \ + AM_HAL_GPIO_WTS(ui32BitNum) = AM_HAL_GPIO_WTS_M(ui32BitNum); \ + } \ + else \ + { \ + AM_HAL_GPIO_WTC(ui32BitNum) = AM_HAL_GPIO_WTC_M(ui32BitNum); \ + } + +//***************************************************************************** +// +//! @brief Toggle the output state of one GPIO. +//! +//! @param ui32BitNum - GPIO number. +//! +//! This function toggles the output state of one GPIO. +//! +//! @return None. +// +//***************************************************************************** +#define am_hal_gpio_out_bit_toggle(ui32BitNum) \ + if ( 1 ) \ + { \ + AM_CRITICAL_BEGIN_ASM \ + AM_HAL_GPIO_WT(ui32BitNum) ^= AM_HAL_GPIO_WT_M(ui32BitNum); \ + AM_CRITICAL_END_ASM \ + } + +//***************************************************************************** +// +//! @brief Sets the output enable for one GPIO. +//! +//! @param ui32BitNum - GPIO number. +//! +//! This function sets the output enable for one GPIO. +//! +//! @return None. +// +//***************************************************************************** +#define am_hal_gpio_out_enable_bit_set(ui32BitNum) \ + AM_HAL_GPIO_ENS(ui32BitNum) = AM_HAL_GPIO_ENS_M(ui32BitNum) + +//***************************************************************************** +// +//! @brief Clears the output enable for one GPIO. +//! +//! @param ui32BitNum - GPIO number. +//! +//! This function clears the output enable for one GPIO. +//! +//! @return None. +// +//***************************************************************************** +#define am_hal_gpio_out_enable_bit_clear(ui32BitNum) \ + AM_HAL_GPIO_ENC(ui32BitNum) = AM_HAL_GPIO_ENC_M(ui32BitNum) + +//***************************************************************************** +// +// Function pointer type for GPIO interrupt handlers. +// +//***************************************************************************** +typedef void (*am_hal_gpio_handler_t)(void); + +//***************************************************************************** +// +// External function prototypes +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +extern uint32_t am_hal_gpio_pin_config_read(uint32_t ui32PinNumber); +extern uint64_t am_hal_gpio_input_read(void); +extern uint64_t am_hal_gpio_out_read(void); +extern uint32_t am_hal_gpio_out_enable_bit_get(uint32_t ui32BitNum); +extern uint64_t am_hal_gpio_out_enable_get(void); +extern void am_hal_gpio_int_enable(uint64_t ui64InterruptMask); +extern uint64_t am_hal_gpio_int_enable_get(void); +extern void am_hal_gpio_int_disable(uint64_t ui64InterruptMask); +extern void am_hal_gpio_int_clear(uint64_t ui64InterruptMask); +extern void am_hal_gpio_int_set(uint64_t ui64InterruptMask); +extern uint64_t am_hal_gpio_int_status_get(bool bEnabledOnly); +extern void am_hal_gpio_int_service(uint64_t ui64Status); +extern void am_hal_gpio_int_register(uint32_t ui32GPIONumber, + am_hal_gpio_handler_t pfnHandler); + +extern bool am_hal_gpio_int_polarity_bit_get(uint32_t ui32BitNum); + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_GPIO_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_i2c_bit_bang.c b/bsp/apollo2/libraries/drivers/hal/am_hal_i2c_bit_bang.c new file mode 100644 index 0000000000..603dd8c4ec --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_i2c_bit_bang.c @@ -0,0 +1,757 @@ +//***************************************************************************** +// +// am_hal_i2c_bit_bang.c +//! @file +//! +//! @brief I2C bit bang module. +//! +//! These functions implement the I2C bit bang utility +//! It implements an I2C interface at close to 400 kHz +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include + +#include "am_mcu_apollo.h" +#include "am_util.h" +#include "am_hal_i2c_bit_bang.h" + +// Max number of clock cycles to wait for clock stretch +#define I2C_BB_MAX_CLOCK_STRETCH_WAIT 100 + +#define I2C_BB_DESIRED_FREQ_HZ 400000 + +#define I2C_BB_CYCLES_PER_DELAY_COUNT 3 +#define I2C_BB_ONE_BIT_TIME_IN_CYCLES (AM_HAL_CLKGEN_FREQ_MAX_HZ/I2C_BB_DESIRED_FREQ_HZ) +#define I2C_BB_ONE_BIT_TIME_IN_DELAY_COUNT (I2C_BB_ONE_BIT_TIME_IN_CYCLES/I2C_BB_CYCLES_PER_DELAY_COUNT) + +// Number of loops (each worth 3 cycles) needed to delay for defined time +// This is imprecise, as there is a setup time as well which is not accounted +// for +// One Bit time = 120 Cycles (400 kHz @ 48 MHz) +#define HALF_BIT_TIME (I2C_BB_ONE_BIT_TIME_IN_DELAY_COUNT/2) +#define QUARTER_BIT_TIME (I2C_BB_ONE_BIT_TIME_IN_DELAY_COUNT/4) +#define ASM_DELAY am_hal_flash_delay + +// Empirically determined adjustments to account for the fact that there is a +// variable time spent in actual processing as well, and hence we need not delay +// for the full time. This processing time is variable based on exact processing +// needed at various times, and will also vary based on compiler type and +// optimization levels +#define I2C_BB_TIMER_ADJUST 6 // Can not be more than QUARTER_BIT_TIME - 1 +#define I2C_BB_TIMER_HI_ADJUST 15 // Can not be more than HALF_BIT_TIME - 1 +#define I2C_BB_TIMER_LO_ADJUST 13 // Can not be more than HALF_BIT_TIME - 1 + +// Wait till it is time to end the SCL Hi Period +#define WAIT_I2C_CLOCK_HI_PERIOD() ASM_DELAY(HALF_BIT_TIME - I2C_BB_TIMER_HI_ADJUST) +// Wait till it is time to end the SCL Lo Period +#define WAIT_I2C_CLOCK_LOW_PERIOD() ASM_DELAY(HALF_BIT_TIME - I2C_BB_TIMER_LO_ADJUST) +// Delay for Quarter Clock +#define WAIT_FOR_QUARTER_I2C_CLOCK() ASM_DELAY(QUARTER_BIT_TIME - I2C_BB_TIMER_ADJUST) +#define WRITE_SCL_LO() \ + do { \ + AM_REGVAL(am_hal_i2c_bit_bang_priv.sck_reg_clr_addr) = (am_hal_i2c_bit_bang_priv.sck_reg_val); \ + } while(0) + +#define PULL_SCL_HI() \ + do { \ + AM_REGVAL(am_hal_i2c_bit_bang_priv.sck_reg_set_addr) = (am_hal_i2c_bit_bang_priv.sck_reg_val); \ + } while(0) + +#define GET_SCL() (AM_REGVAL(am_hal_i2c_bit_bang_priv.sck_reg_read_addr) & (am_hal_i2c_bit_bang_priv.sck_reg_val)) +#define GET_SDA() (AM_REGVAL(am_hal_i2c_bit_bang_priv.sda_reg_read_addr) & (am_hal_i2c_bit_bang_priv.sda_reg_val)) + +#define WRITE_SDA_LO() \ + do { \ + AM_REGVAL(am_hal_i2c_bit_bang_priv.sda_reg_clr_addr) = (am_hal_i2c_bit_bang_priv.sda_reg_val); \ + } while(0) + +#define PULL_SDA_HI() \ + do { \ + AM_REGVAL(am_hal_i2c_bit_bang_priv.sda_reg_set_addr) = (am_hal_i2c_bit_bang_priv.sda_reg_val); \ + } while(0) + + +//***************************************************************************** +// +// I2C Bit Bang Private Data Structure +// +//***************************************************************************** +typedef struct am_util_bit_bang_priv +{ + bool start_flag; + uint32_t sck_gpio_number; + uint32_t sda_gpio_number; + uint32_t sck_reg_set_addr; + uint32_t sck_reg_clr_addr; + uint32_t sck_reg_read_addr; + uint32_t sck_reg_val; + uint32_t sda_reg_set_addr; + uint32_t sda_reg_clr_addr; + uint32_t sda_reg_read_addr; + uint32_t sda_reg_val; +} am_hal_i2c_bit_bang_priv_t; +static am_hal_i2c_bit_bang_priv_t am_hal_i2c_bit_bang_priv; + +// +// Wait for any stretched clock to go high +// If it times out - return failure +// +static inline bool +i2c_pull_and_wait_scl_hi(void) +{ + // Maximum time to wait for clock stretching + uint32_t maxLoop = 4*I2C_BB_MAX_CLOCK_STRETCH_WAIT + 1; + // Pull SCL High + PULL_SCL_HI(); + // Poll for SCL to check for clock stretching + while (!GET_SCL()) + { + if (--maxLoop == 0) + { + // timeout! + return true; + } + WAIT_FOR_QUARTER_I2C_CLOCK(); + } + return false; +} + +//***************************************************************************** +// +//! @brief Initialize i2c bit bang private data structure +//! +//! @param sck_gpio_number is the GPIO # for the I2C SCK clock pin +//! @param sda_gpio_number is the GPIO # for the I2C SDA data pin +//! +//! This function initializes the I2C bit bang utility's internal data struct. +//! +//! returns None. +// +//***************************************************************************** +am_hal_i2c_bit_bang_enum_t +am_hal_i2c_bit_bang_init(uint32_t sck_gpio_number, + uint32_t sda_gpio_number) +{ + int i; + // + // remember GPIO pin assignments for I2C bus signals + // + am_hal_i2c_bit_bang_priv.sck_gpio_number = sck_gpio_number; + am_hal_i2c_bit_bang_priv.sda_gpio_number = sda_gpio_number; + + am_hal_i2c_bit_bang_priv.sck_reg_set_addr = AM_HAL_GPIO_WTS_REG(sck_gpio_number); + am_hal_i2c_bit_bang_priv.sck_reg_clr_addr = AM_HAL_GPIO_WTC_REG(sck_gpio_number); + am_hal_i2c_bit_bang_priv.sck_reg_read_addr = AM_HAL_GPIO_RD_REG(sck_gpio_number); + am_hal_i2c_bit_bang_priv.sck_reg_val = AM_HAL_GPIO_WTC_M(sck_gpio_number); + am_hal_i2c_bit_bang_priv.sda_reg_set_addr = AM_HAL_GPIO_WTS_REG(sda_gpio_number); + am_hal_i2c_bit_bang_priv.sda_reg_clr_addr = AM_HAL_GPIO_WTC_REG(sda_gpio_number); + am_hal_i2c_bit_bang_priv.sda_reg_read_addr = AM_HAL_GPIO_RD_REG(sda_gpio_number); + am_hal_i2c_bit_bang_priv.sda_reg_val = AM_HAL_GPIO_WTC_M(sda_gpio_number); + + // + // Set SCK GPIO data bit high so we aren't pulling down the clock + // + am_hal_gpio_out_bit_set(sck_gpio_number); + // + // Set up SCK GPIO configuration bi-direction, input + // + am_hal_gpio_pin_config(sck_gpio_number, AM_HAL_PIN_OPENDRAIN); + + // + // Set SDA GPIO data bit high so we aren't pulling down the data line + // + am_hal_gpio_out_bit_set(sda_gpio_number); + // + // Set up SDA GPIO configuration bi-direction, input + // + am_hal_gpio_pin_config(sda_gpio_number, AM_HAL_PIN_OPENDRAIN); + + // Now make sure we have control of the clock line + // + // Wait for any stretched clock to go high. Return if still not high + // + if (i2c_pull_and_wait_scl_hi()) + { + return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT; + } + if (!GET_SDA()) + { + // If previous transaction did not finish - SDA may be pulled low for a Read. + // If so - need to flush out the data (max 8 bits) & NACK + for (i = 0; i < 9; i++) + { + // + // Pull down on clock line + // + WRITE_SCL_LO(); + // + // Delay for 1/2 bit cell time to start the clock and let peer write on SDA + // + WAIT_I2C_CLOCK_LOW_PERIOD(); + if (i2c_pull_and_wait_scl_hi()) + { + return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT; + } + if (GET_SDA()) + { + // Send START/STOP to clear the bus + // + // Delay for 1/4 bit cell time + // + WAIT_FOR_QUARTER_I2C_CLOCK(); + WRITE_SDA_LO(); + // + // Delay for 1/4 bit cell time + // + WAIT_FOR_QUARTER_I2C_CLOCK(); + // + // Pull down on clock line + // + WRITE_SCL_LO(); + // + // Delay for 1/2 bit cell time to start the clock and let peer write on SDA + // + WAIT_I2C_CLOCK_LOW_PERIOD(); + // + // Release the clock line + // + PULL_SCL_HI(); + // + // Delay for 1/4 bit cell time + // + WAIT_FOR_QUARTER_I2C_CLOCK(); + PULL_SDA_HI(); + // + // Delay for 1/4 bit cell time + // + WAIT_FOR_QUARTER_I2C_CLOCK(); + break; + } + } + if (i == 9) + { + // It is it still stuck after 9 clocks - something is wrong. Need to bail out + return AM_HAL_I2C_BIT_BANG_DATA_TIMEOUT; + } + } + return AM_HAL_I2C_BIT_BANG_SUCCESS; +} + +//***************************************************************************** +// +//! @brief Receive one data byte from an I2C device +//! +//! This function handles sending one byte to a slave device +//! bNack defines if we should send an ACK or NACK +//! +//! returns the byte received +// +//***************************************************************************** +static inline am_hal_i2c_bit_bang_enum_t +i2c_receive_byte(uint8_t *pRxByte, bool bNack) +{ + int i; + uint8_t data_byte = 0; + + // + // Loop through receiving 8 bits + // + for (i = 0; i < 8; i++) + { + // + // Pull down on clock line + // + WRITE_SCL_LO(); + + // + // release the data line from from the previous ACK + // + PULL_SDA_HI(); + + // + // Delay for 1/2 bit cell time to start the clock and let peer write on SDA + // + WAIT_I2C_CLOCK_LOW_PERIOD(); + + if (i2c_pull_and_wait_scl_hi()) + { + return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT; + } + // + // grab the data bit here + // + if ( GET_SDA() ) + { + // + // set the bit in the data byte to be returned + // + data_byte |= (0x80 >> i); + } + + // + // Delay for 1/2 bit cell time while clock is high + // + WAIT_I2C_CLOCK_HI_PERIOD(); + } + + *pRxByte = data_byte; + // + // Pull down on clock line + // + WRITE_SCL_LO(); + + // + // pull the data line down so we can ACK/NAK the byte we just received + // + if (bNack) + { + // + // Pull up on data line with clock low to indicate NAK + // + PULL_SDA_HI(); + } + else + { + // + // Pull down on data line with clock low to indicate ACK + // + WRITE_SDA_LO(); + } + // + // Delay for 1/2 bit cell time before sending ACK to device + // + WAIT_I2C_CLOCK_LOW_PERIOD(); + + if (i2c_pull_and_wait_scl_hi()) + { + return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT; + } + // + // Delay for 1/2 bit cell time while clock is high to le peer sample the ACK/NAK + // + WAIT_I2C_CLOCK_HI_PERIOD(); + // + // Give the received data byte back to them + // + return AM_HAL_I2C_BIT_BANG_SUCCESS; +} + +//***************************************************************************** +// +//! @brief Send one data bytes to an I2C device +//! +//! @param one_byte the byte to send, could be address could be data +//! +//! This function handles sending one byte to a slave device +//! Starts with 0 clock and runs till full cycle +//! +//! returns I2C BB ENUM +//! { +//! AM_HAL_I2C_BIT_BANG_SUCCESS, +//! AM_HAL_I2C_BIT_BANG_ADDRESS_NAKED +//! } +// +//***************************************************************************** +static inline am_hal_i2c_bit_bang_enum_t +i2c_send_byte(uint8_t one_byte) +{ + int i; + bool data_naked = false; + + // + // Loop through sending 8 bits + // + for (i = 0; i < 8; i++) + { + // + // Pull down on clock line + // + WRITE_SCL_LO(); + + // + // output the next data bit + // + if ( one_byte & (0x80 >> i) ) + { + PULL_SDA_HI(); + } + else + { + WRITE_SDA_LO(); + } + + // + // Delay for 1/2 bit cell time to start the clock + // + WAIT_I2C_CLOCK_LOW_PERIOD(); + + if (i2c_pull_and_wait_scl_hi()) + { + return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT; + } + // + // Delay for 1/2 bit cell time while clock is high + // + WAIT_I2C_CLOCK_HI_PERIOD(); + } + + // + // Pull down on clock line + // + WRITE_SCL_LO(); + + // + // Delay for 1/2 bit cell time to start the clock + // + WAIT_I2C_CLOCK_LOW_PERIOD(); + + if (i2c_pull_and_wait_scl_hi()) + { + return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT; + } + // + // Grab the state of the ACK bit and return it + // + data_naked = GET_SDA(); + // + // Delay for 1/2 bit cell time to complete the high period + // + WAIT_I2C_CLOCK_HI_PERIOD(); + if ( data_naked ) + { + return AM_HAL_I2C_BIT_BANG_DATA_NAKED; + } + else + { + return AM_HAL_I2C_BIT_BANG_SUCCESS; + } +} + +//***************************************************************************** +// +//! @brief Receive a string of data bytes from an I2C device +//! +//! @param address (only 8 bit I2C addresses are supported) +//! LSB is I2C R/W +//! @param number_of_bytes to transfer (# payload bytes) +//! @param pData pointer to data buffer to receive payload +//! +//! This function handles receiving a payload from a slave device +//! +//! returns ENUM{AM_HAL_I2C_BIT_BANG_SUCCESS,AM_HAL_I2C_BIT_BANG_ADDRESS_NAKED} +// +//***************************************************************************** +am_hal_i2c_bit_bang_enum_t +am_hal_i2c_bit_bang_receive(uint8_t address, uint32_t number_of_bytes, + uint8_t *pData, uint8_t ui8Offset, + bool bUseOffset, bool bNoStop) +{ + uint32_t ui32I; + am_hal_i2c_bit_bang_enum_t status = AM_HAL_I2C_BIT_BANG_SUCCESS; + + + if (i2c_pull_and_wait_scl_hi()) + { + return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT; + } + // + // Pull down on data line with clock high --> START CONDITION + // + WRITE_SDA_LO(); + + // + // Delay for 1/2 bit cell time to start the clock + // + WAIT_I2C_CLOCK_HI_PERIOD(); + + // + // send the address byte and wait for the ACK/NAK + // + status = i2c_send_byte(address); + if ( status != AM_HAL_I2C_BIT_BANG_SUCCESS ) + { + if ( status == AM_HAL_I2C_BIT_BANG_DATA_NAKED) + { + return AM_HAL_I2C_BIT_BANG_ADDRESS_NAKED; + } + return status; + } + + if ( bUseOffset ) + { + status = i2c_send_byte(ui8Offset); + if ( status != AM_HAL_I2C_BIT_BANG_SUCCESS ) + { + return status; + } + } + + // + // receive the requested number of data bytes + // + for (ui32I = 0; ui32I < number_of_bytes - 1; ui32I++) + { + // + // receive the data bytes and send ACK for each one + // + status = i2c_receive_byte(pData, false); + if (status != AM_HAL_I2C_BIT_BANG_SUCCESS) + { + return status; + } + pData++; + } + // Send NAK for the last byte + status = i2c_receive_byte(pData, true); + if (status != AM_HAL_I2C_BIT_BANG_SUCCESS) + { + return status; + } + + //******************** + // Send stop condition + //******************** + // + // Pull down on clock line + // + WRITE_SCL_LO(); + + // + // Delay for 1/4 bit cell time + // + WAIT_FOR_QUARTER_I2C_CLOCK(); + + + if (!bNoStop) + { + // + // Pull down on data line with clock low + // + WRITE_SDA_LO(); + } + else + { + // + // Release data line with clock low itself, as we are not sending STOP + // + PULL_SDA_HI(); + } + // + // + // Delay for 1/4 bit cell time + // + WAIT_FOR_QUARTER_I2C_CLOCK(); + + if (i2c_pull_and_wait_scl_hi()) + { + return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT; + } + // + // Delay for 1/2 bit cell time while clock is high + // + WAIT_I2C_CLOCK_HI_PERIOD(); + + if (!bNoStop) + { + // + // release data line with clock high --> STOP CONDITION + // + PULL_SDA_HI(); + } + + // + // message successfully received (how could we fail???) + // + return AM_HAL_I2C_BIT_BANG_SUCCESS; +} + +//***************************************************************************** +// +//! @brief Send a string of data bytes to an I2C device +//! +//! @param address (only 8 bit I2C addresses are supported) +//! LSB is I2C R/W +//! @param number_of_bytes to transfer (# payload bytes) +//! @param pData pointer to data buffer containing payload +//! +//! This function handles sending a payload to a slave device +//! +//! returns ENUM {AM_HAL_I2C_BIT_BANG_SUCCESS, AM_HAL_I2C_BIT_BANG_DATA_NAKED, +//! AM_HAL_I2C_BIT_BANG_ADDRESS_NAKED} +// +//***************************************************************************** +am_hal_i2c_bit_bang_enum_t +am_hal_i2c_bit_bang_send(uint8_t address, uint32_t number_of_bytes, + uint8_t *pData, uint8_t ui8Offset, + bool bUseOffset, bool bNoStop) +{ + uint32_t ui32I; + am_hal_i2c_bit_bang_enum_t status; + bool data_naked = false; + + if (i2c_pull_and_wait_scl_hi()) + { + return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT; + } + // + // Pull down on data line with clock high --> START CONDITION + // + WRITE_SDA_LO(); + + // + // Delay for 1/2 bit cell time to start the clock + // + WAIT_I2C_CLOCK_HI_PERIOD(); + + // + // send the address byte and wait for the ACK/NAK + // + status = i2c_send_byte(address); + if ( status != AM_HAL_I2C_BIT_BANG_SUCCESS ) + { + if ( status == AM_HAL_I2C_BIT_BANG_DATA_NAKED) + { + return AM_HAL_I2C_BIT_BANG_ADDRESS_NAKED; + } + return status; + } + + if ( bUseOffset ) + { + status = i2c_send_byte(ui8Offset); + if ( status != AM_HAL_I2C_BIT_BANG_SUCCESS ) + { + return status; + } + } + + // + // send the requested number of data bytes + // + for (ui32I = 0; ui32I < number_of_bytes; ui32I++) + { + // + // send out the data bytes while watching for premature NAK + // + status = i2c_send_byte(*pData++); + if (status != AM_HAL_I2C_BIT_BANG_SUCCESS) + { + if (status == AM_HAL_I2C_BIT_BANG_DATA_NAKED) + { + if (ui32I != (number_of_bytes-1)) + { + data_naked = true; + // TODO - should we be sending the STOP bit in this case regardless of bNoStop? + break; + } + else + { + status = AM_HAL_I2C_BIT_BANG_SUCCESS; + } + } + else + { + return status; + } + } + } + + //******************** + // Send stop condition + //******************** + + // + // Pull down on clock line + // + WRITE_SCL_LO(); + + // + // Delay for 1/4 bit cell time + // + WAIT_FOR_QUARTER_I2C_CLOCK(); + + + if (!bNoStop) + { + // + // Pull down on data line with clock low + // + WRITE_SDA_LO(); + } + else + { + // + // Release data line with clock low itself, as we are not sending STOP + // + PULL_SDA_HI(); + } + + // + // Delay for 1/4 bit cell time + // + WAIT_FOR_QUARTER_I2C_CLOCK(); + + if (i2c_pull_and_wait_scl_hi()) + { + return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT; + } + if (!bNoStop) + { + // + // release data line with clock high --> STOP CONDITION + // + PULL_SDA_HI(); + } + + // + // Delay for 1/2 bit cell time while clock is high + // + WAIT_I2C_CLOCK_HI_PERIOD(); + + if ( data_naked ) + { + return AM_HAL_I2C_BIT_BANG_DATA_NAKED; // if it happens early + } + + // + // message successfully sent + // + return AM_HAL_I2C_BIT_BANG_SUCCESS; +} diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_i2c_bit_bang.h b/bsp/apollo2/libraries/drivers/hal/am_hal_i2c_bit_bang.h new file mode 100644 index 0000000000..a9571edbe5 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_i2c_bit_bang.h @@ -0,0 +1,100 @@ +//***************************************************************************** +// +// am_hal_i2c_bit_bang.h +//! @file +//! +//! @brief I2C bit bang module. +//! +//! These functions implement the I2C bit bang utility +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_I2C_BIT_BANG_H +#define AM_HAL_I2C_BIT_BANG_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Enumerated return constants +// +//***************************************************************************** +typedef enum +{ + AM_HAL_I2C_BIT_BANG_SUCCESS = 0, + AM_HAL_I2C_BIT_BANG_ADDRESS_NAKED, + AM_HAL_I2C_BIT_BANG_DATA_NAKED, + AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT, + AM_HAL_I2C_BIT_BANG_DATA_TIMEOUT, +}am_hal_i2c_bit_bang_enum_t; + +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern am_hal_i2c_bit_bang_enum_t am_hal_i2c_bit_bang_init(uint32_t sck_gpio_number, + uint32_t sda_gpio_number); + +extern am_hal_i2c_bit_bang_enum_t am_hal_i2c_bit_bang_send(uint8_t address, + uint32_t number_of_bytes, + uint8_t *pData, + uint8_t ui8Offset, + bool bUseOffset, + bool bNoStop); + +extern am_hal_i2c_bit_bang_enum_t am_hal_i2c_bit_bang_receive(uint8_t address, + uint32_t number_of_bytes, + uint8_t *pData, + uint8_t ui8Offset, + bool bUseOffset, + bool bNoStop); +#ifdef __cplusplus +} +#endif + +#endif //AM_HAL_I2C_BIT_BANG_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_interrupt.c b/bsp/apollo2/libraries/drivers/hal/am_hal_interrupt.c new file mode 100644 index 0000000000..2f93b09cfc --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_interrupt.c @@ -0,0 +1,407 @@ +//***************************************************************************** +// +// am_hal_interrupt.c +//! @file +//! +//! @brief Helper functions supporting interrupts and NVIC operation. +//! +//! These functions may be used for NVIC-level interrupt configuration. +//! +//! @addtogroup interrupt2 Interrupt (ARM NVIC support functions) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +//! @brief Enable an interrupt. +//! +//! @param ui32Interrupt The ISR number of the interrupt to be enabled. +//! +//! This function enables an interrupt signal to the NVIC based on the provided +//! ISR number. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_interrupt_enable(uint32_t ui32Interrupt) +{ + // + // Check to see what type of interrupt this is. + // + if ( ui32Interrupt > 15 ) + { + // + // If this ISR number corresponds to a "normal" peripheral interrupt, + // enable it using the NVIC register. + // + AM_REG(NVIC, ISER0) = 0x1 << ((ui32Interrupt - 16) & 0x1F); + } + else + { + // + // If this is an ARM internal interrupt number, route it to the + // appropriate enable register. + // + switch(ui32Interrupt) + { + case AM_HAL_INTERRUPT_BUSFAULT: + AM_BFW(SYSCTRL, SHCSR, BUSFAULTENA, 1); + break; + + case AM_HAL_INTERRUPT_USAGEFAULT: + AM_BFW(SYSCTRL, SHCSR, USAGEFAULTENA, 1); + break; + + case AM_HAL_INTERRUPT_MPUFAULT: + AM_BFW(SYSCTRL, SHCSR, MEMFAULTENA, 1); + break; + } + } +} + +//***************************************************************************** +// +//! @brief Disable an interrupt. +//! +//! @param ui32Interrupt The ISR number of the interrupt to be disabled. +//! +//! This function disables an interrupt signal to the NVIC based on the +//! provided ISR number. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_interrupt_disable(uint32_t ui32Interrupt) +{ + // + // Check to see what type of interrupt this is. + // + if ( ui32Interrupt > 15 ) + { + // + // If this ISR number corresponds to a "normal" peripheral interrupt, + // disable it using the NVIC register. + // + AM_REG(NVIC, ICER0) = 0x1 << ((ui32Interrupt - 16) & 0x1F); + } + else + { + // + // If this is an ARM internal interrupt number, route it to the + // appropriate enable register. + // + switch(ui32Interrupt) + { + case AM_HAL_INTERRUPT_BUSFAULT: + AM_BFW(SYSCTRL, SHCSR, BUSFAULTENA, 0); + break; + + case AM_HAL_INTERRUPT_USAGEFAULT: + AM_BFW(SYSCTRL, SHCSR, USAGEFAULTENA, 0); + break; + + case AM_HAL_INTERRUPT_MPUFAULT: + AM_BFW(SYSCTRL, SHCSR, MEMFAULTENA, 0); + break; + } + } +} + +//***************************************************************************** +// +//! @brief Set the priority of an interrupt vector. +//! +//! @param ui32Interrupt is the ISR number of the interrupt to change. +//! @param ui32Priority is the new ISR priority value. +//! +//! This function changes the priority value in the NVIC for the given +//! interrupt vector number. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_interrupt_priority_set(uint32_t ui32Interrupt, uint32_t ui32Priority) +{ + volatile uint32_t *pui32PriorityReg; + volatile uint32_t ui32OldPriority; + uint32_t ui32Shift; + + // + // Find the correct priority register. + // + pui32PriorityReg = (volatile uint32_t *) AM_REG_NVIC_IPR0_O; + pui32PriorityReg += ((ui32Interrupt - 16) >> 2); + + // + // Find the correct shift value. + // + ui32Shift = (((ui32Interrupt - 16) & 0x3) * 8); + + // + // Mask out the old priority. + // + ui32OldPriority = *pui32PriorityReg; + ui32OldPriority &= ~(0xFF << ui32Shift); + + // + // OR in the new priority. + // + *pui32PriorityReg |= (ui32Priority << ui32Shift); +} + +//***************************************************************************** +// +//! @brief Set a pending interrupt bit in the NVIC (Software Interrupt) +//! +//! @param ui32Interrupt is the ISR number of the interrupt to change. +//! +//! This function sets the specified bit in the Interrupt Set Pending (ISPR0) +//! register. For future MCUs there may be more than one ISPR. +//! +//! @return None +// +//***************************************************************************** +void am_hal_interrupt_pend_set(uint32_t ui32Interrupt) +{ + // + // Check to see if the specified interrupt is valid for this MCU + // + if ( ui32Interrupt > 47 ) + { + return; + } + + // + // Check to see what type of interrupt this is. + // + if ( ui32Interrupt > 15 ) + { + // + // If this ISR number corresponds to a "normal" peripheral interrupt, + // disable it using the NVIC register. + // + AM_REG(NVIC, ISPR0) = 0x1 << ((ui32Interrupt - 16) & 0x1F); + } +} + +//***************************************************************************** +// +//! @brief Clear a pending interrupt bit in the NVIC without servicing it +//! +//! @param ui32Interrupt is the ISR number of the interrupt to change. +//! +//! This function clears the specified bit in the Interrupt Clear Pending +//! (ICPR0) register. For future MCUs there may be more than one ICPR. This +//! function is useful immediately following a WFI before interrupts are +//! re-enabled. +//! +//! @return None +// +//***************************************************************************** +void am_hal_interrupt_pend_clear(uint32_t ui32Interrupt) +{ + // + // Check to see if the specified interrupt is valid for this MCU + // + if ( ui32Interrupt > 47 ) + { + return; + } + + // + // Check to see what type of interrupt this is. + // + if ( ui32Interrupt > 15 ) + { + // + // If this ISR number corresponds to a "normal" peripheral interrupt, + // disable it using the NVIC register. + // + AM_REG(NVIC, ICPR0) = 0x1 << ((ui32Interrupt - 16) & 0x1F); + } +} + +//***************************************************************************** +// +//! @brief Globally enable interrupt service routines +//! +//! This function allows interrupt signals from the NVIC to trigger ISR entry +//! in the CPU. This function must be called if interrupts are to be serviced +//! in software. +//! +//! @return 1 if interrupts were previously disabled, 0 otherwise. +// +//***************************************************************************** +#if defined(__GNUC_STDC_INLINE__) +uint32_t __attribute__((naked)) +am_hal_interrupt_master_enable(void) +{ + __asm(" mrs r0, PRIMASK"); + __asm(" cpsie i"); + __asm(" bx lr"); +} +#elif defined(__ARMCC_VERSION) +__asm uint32_t +am_hal_interrupt_master_enable(void) +{ + mrs r0, PRIMASK + cpsie i + bx lr +} +#elif defined(__IAR_SYSTEMS_ICC__) +#pragma diag_suppress = Pe940 // Suppress IAR compiler warning about missing + // return statement on a non-void function +__stackless uint32_t +am_hal_interrupt_master_enable(void) +{ + __asm(" mrs r0, PRIMASK"); + __asm(" cpsie i"); + __asm(" bx lr"); +} +#pragma diag_default = Pe940 // Restore IAR compiler warning +#endif + +//***************************************************************************** +// +//! @brief Globally disable interrupt service routines +//! +//! This function prevents interrupt signals from the NVIC from triggering ISR +//! entry in the CPU. This will effectively stop incoming interrupt sources +//! from triggering their corresponding ISRs. +//! +//! @note Any external interrupt signal that occurs while the master interrupt +//! disable is active will still reach the "pending" state in the NVIC, but it +//! will not be allowed to reach the "active" state or trigger the +//! corresponding ISR. Instead, these interrupts are essentially "queued" until +//! the next time the master interrupt enable instruction is executed. At that +//! time, the interrupt handlers will be executed in order of decreasing +//! priority. +//! +//! @return 1 if interrupts were previously disabled, 0 otherwise. +// +//***************************************************************************** +#if defined(__GNUC_STDC_INLINE__) +uint32_t __attribute__((naked)) +am_hal_interrupt_master_disable(void) +{ + __asm(" mrs r0, PRIMASK"); + __asm(" cpsid i"); + __asm(" bx lr"); +} +#elif defined(__ARMCC_VERSION) +__asm uint32_t +am_hal_interrupt_master_disable(void) +{ + mrs r0, PRIMASK + cpsid i + bx lr +} +#elif defined(__IAR_SYSTEMS_ICC__) +#pragma diag_suppress = Pe940 // Suppress IAR compiler warning about missing + // return statement on a non-void function +__stackless uint32_t +am_hal_interrupt_master_disable(void) +{ + __asm(" mrs r0, PRIMASK"); + __asm(" cpsid i"); + __asm(" bx lr"); +} +#pragma diag_default = Pe940 // Restore IAR compiler warning +#endif + +//***************************************************************************** +// +//! @brief Sets the master interrupt state based on the input. +//! +//! @param ui32InterruptState - Desired PRIMASK value. +//! +//! This function directly writes the PRIMASK register in the ARM core. A value +//! of 1 will disable interrupts, while a value of zero will enable them. +//! +//! This function may be used along with am_hal_interrupt_master_disable() to +//! implement a nesting critical section. To do this, call +//! am_hal_interrupt_master_disable() to start the critical section, and save +//! its return value. To complete the critical section, call +//! am_hal_interrupt_master_set() using the saved return value as \e +//! ui32InterruptState. This will safely restore PRIMASK to the value it +//! contained just before the start of the critical section. +//! +//! @return None. +// +//***************************************************************************** +#if defined(__GNUC_STDC_INLINE__) +void __attribute__((naked)) +am_hal_interrupt_master_set(uint32_t ui32InterruptState) +{ + __asm(" msr PRIMASK, r0"); + __asm(" bx lr"); +} +#elif defined(__ARMCC_VERSION) +__asm void +am_hal_interrupt_master_set(uint32_t ui32InterruptState) +{ + msr PRIMASK, r0 + bx lr +} +#elif defined(__IAR_SYSTEMS_ICC__) +#pragma diag_suppress = Pe940 // Suppress IAR compiler warning about missing + // return statement on a non-void function +__stackless void +am_hal_interrupt_master_set(uint32_t ui32InterruptState) +{ + __asm(" msr PRIMASK, r0"); + __asm(" bx lr"); +} +#pragma diag_default = Pe940 // Restore IAR compiler warning +#endif + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_interrupt.h b/bsp/apollo2/libraries/drivers/hal/am_hal_interrupt.h new file mode 100644 index 0000000000..a8523371eb --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_interrupt.h @@ -0,0 +1,159 @@ +//***************************************************************************** +// +// am_hal_interrupt.h +//! @file +//! +//! @brief Helper functions supporting interrupts and NVIC operation. +//! +//! These functions may be used for NVIC-level interrupt configuration. +//! +//! @addtogroup interrupt2 Interrupt (ARM NVIC support functions) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_INTERRUPT_H +#define AM_HAL_INTERRUPT_H + +#ifdef __cplusplus +extern "C" +{ +#endif +//***************************************************************************** +// +//! @name ISR number macros. +//! @brief ISR macros. +//! +//! These macros are used for all ui32Interrupt arguments in this module. +//! @{ +// +//***************************************************************************** +// +// Hardware interrupts +// +#define AM_HAL_INTERRUPT_RESET 1 +#define AM_HAL_INTERRUPT_NMI 2 +#define AM_HAL_INTERRUPT_HARDFAULT 3 +#define AM_HAL_INTERRUPT_MPUFAULT 4 +#define AM_HAL_INTERRUPT_BUSFAULT 5 +#define AM_HAL_INTERRUPT_USAGEFAULT 6 + +#define AM_HAL_INTERRUPT_SVCALL 11 +#define AM_HAL_INTERRUPT_DEBUGMON 12 +#define AM_HAL_INTERRUPT_PENDSV 14 +#define AM_HAL_INTERRUPT_SYSTICK 15 + +// +// Begin IRQs +// +#define AM_HAL_INTERRUPT_BROWNOUT 16 +#define AM_HAL_INTERRUPT_WATCHDOG 17 +#define AM_HAL_INTERRUPT_CLKGEN 18 +#define AM_HAL_INTERRUPT_VCOMP 19 +#define AM_HAL_INTERRUPT_IOSLAVE 20 +#define AM_HAL_INTERRUPT_IOSACC 21 +#define AM_HAL_INTERRUPT_IOMASTER0 22 +#define AM_HAL_INTERRUPT_IOMASTER1 23 +#define AM_HAL_INTERRUPT_IOMASTER2 24 +#define AM_HAL_INTERRUPT_IOMASTER3 25 +#define AM_HAL_INTERRUPT_IOMASTER4 26 +#define AM_HAL_INTERRUPT_IOMASTER5 27 +#define AM_HAL_INTERRUPT_GPIO 28 +#define AM_HAL_INTERRUPT_CTIMER 29 +#define AM_HAL_INTERRUPT_UART0 30 +#define AM_HAL_INTERRUPT_UART1 31 +#define AM_HAL_INTERRUPT_UART (AM_HAL_INTERRUPT_UART0) +#define AM_HAL_INTERRUPT_ADC 32 +#define AM_HAL_INTERRUPT_PDM 33 +#define AM_HAL_INTERRUPT_STIMER 34 +#define AM_HAL_INTERRUPT_STIMER_CMPR0 35 +#define AM_HAL_INTERRUPT_STIMER_CMPR1 36 +#define AM_HAL_INTERRUPT_STIMER_CMPR2 37 +#define AM_HAL_INTERRUPT_STIMER_CMPR3 38 +#define AM_HAL_INTERRUPT_STIMER_CMPR4 39 +#define AM_HAL_INTERRUPT_STIMER_CMPR5 40 +#define AM_HAL_INTERRUPT_STIMER_CMPR6 41 +#define AM_HAL_INTERRUPT_STIMER_CMPR7 42 +#define AM_HAL_INTERRUPT_FLASH 43 + +#define AM_HAL_INTERRUPT_SOFTWARE0 44 +#define AM_HAL_INTERRUPT_SOFTWARE1 45 +#define AM_HAL_INTERRUPT_SOFTWARE2 46 +#define AM_HAL_INTERRUPT_SOFTWARE3 47 +//! @} + +//***************************************************************************** +// +//! @brief Interrupt priority +//! +//! This macro is made to be used with the \e am_hal_interrupt_priority_set() +//! function. It converts a priority number to the format used by the ARM +//! standard priority register, where only the top 3 bits are used. +//! +//! For example, AM_HAL_INTERRUPT_PRIORITY(1) yields a value of 0x20. +// +//***************************************************************************** +#define AM_HAL_INTERRUPT_PRIORITY(n) (((uint32_t)(n) & 0x7) << 5) + +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern void am_hal_interrupt_enable(uint32_t ui32Interrupt); +extern void am_hal_interrupt_disable(uint32_t ui32Interrupt); +extern void am_hal_interrupt_pend_set(uint32_t ui32Interrupt); +extern void am_hal_interrupt_pend_clear(uint32_t ui32Interrupt); +extern void am_hal_interrupt_priority_set(uint32_t ui32Interrupt, + uint32_t ui32Priority); +extern uint32_t am_hal_interrupt_master_disable(void); +extern uint32_t am_hal_interrupt_master_enable(void); +extern void am_hal_interrupt_master_set(uint32_t ui32InterruptState); + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_INTERRUPT_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_iom.c b/bsp/apollo2/libraries/drivers/hal/am_hal_iom.c new file mode 100644 index 0000000000..8b85c32b6a --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_iom.c @@ -0,0 +1,4426 @@ +//***************************************************************************** +// +// am_hal_iom.c +//! @file +//! +//! @brief Functions for interfacing with the IO Master module +//! +//! @addtogroup iom2 IO Master (SPI/I2C) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" +#include "am_util_delay.h" + +#ifdef __IAR_SYSTEMS_ICC__ +#define AM_INSTR_CLZ(n) __CLZ(n) +#else +#define AM_INSTR_CLZ(n) __builtin_clz(n) +#endif + +//! ASSERT(1) or Correct(0) invalid IOM R/W Thresholds. +#ifndef AM_ASSERT_INVALID_THRESHOLD +#define AM_ASSERT_INVALID_THRESHOLD (1) +#endif + +//***************************************************************************** +// +// Forcing optimizations +// +// These pragmas must be enabled if we intend to use the IOM4 workaround with a +// delay higher than 18-bits in the first word. +// +//***************************************************************************** +//#ifdef __IAR_SYSTEMS_ICC__ +//#pragma optimize=3 s +//#endif +// +//#ifdef __ARMCC_VERSION +//#pragma O3 +//#endif +// +//#ifdef __GNUC__ +//#pragma GCC optimize ("O3") +//#endif + +//***************************************************************************** +// +// Forward declarations. +// +//***************************************************************************** +static void iom_workaround_loop(uint32_t ui32PadRegVal, + volatile uint32_t *pui32PadReg, + bool bRising); +static uint32_t +internal_am_hal_iom_spi_cmd_construct(uint32_t ui32Operation, + uint32_t ui32ChipSelect, + uint32_t ui32NumBytes, + uint32_t ui32Options); + +//***************************************************************************** +// +// IOM Buffer states. +// +//***************************************************************************** +#define BUFFER_IDLE 0x0 +#define BUFFER_SENDING 0x1 +#define BUFFER_RECEIVING 0x2 + +//***************************************************************************** +// +// Global state variables +// +//***************************************************************************** +// +// Save error status from ISR, particularly for use in I2C queue mode. +// +uint32_t g_iom_error_status = 0; + +// +// Define a structure to map CE for IOM4 only. +// +typedef struct +{ + uint8_t channel; // CE channel for SPI + uint8_t pad; // GPIO Pad + uint8_t funcsel; // FNCSEL value +} IOMPad_t; + +// Define the mapping between SPI CEn, Pads, and FNCSEL values for all IOMs. +const IOMPad_t g_IOMPads[] = +{ + {0, 29, 6}, {0, 34, 6}, {1, 18, 4}, {1, 37, 5}, {2, 41, 6}, + {3, 17, 4}, {3, 45, 4}, {4, 10, 6}, {4, 46, 6}, {5, 9, 4}, + {5, 47, 6}, {6, 35, 4}, {7, 38, 6} +}; + +#define WORKAROUND_IOM 4 +#define WORKAROUND_IOM_MOSI_PIN 44 +#define WORKAROUND_IOM_MOSI_CFG AM_HAL_PIN_44_M4MOSI + +#define MAX_IOM_BITS 9 +#define IOM_OVERHEAD_FACTOR 2 + +//***************************************************************************** +// +// Non-blocking buffer and buffer-management variables. +// +//***************************************************************************** +typedef struct +{ + uint32_t ui32State; + uint32_t *pui32Data; + uint32_t ui32BytesLeft; + uint32_t ui32Options; + void (*pfnCallback)(void); +} +am_hal_iom_nb_buffer; + +// +// Global State to keep track if there is an ongoing transaction +// +volatile bool g_bIomBusy[AM_REG_IOMSTR_NUM_MODULES] = {0}; + +am_hal_iom_nb_buffer g_psIOMBuffers[AM_REG_IOMSTR_NUM_MODULES]; + +//***************************************************************************** +// +// Computed timeout. +// +// The IOM may not always respond to events (e.g., CMDCMP). This is a +// timeout value in cycles to be used when waiting on status changes. +//***************************************************************************** +uint32_t ui32StatusTimeout[AM_REG_IOMSTR_NUM_MODULES]; + +//***************************************************************************** +// +// Queue management variables. +// +//***************************************************************************** +am_hal_queue_t g_psIOMQueue[AM_REG_IOMSTR_NUM_MODULES]; + +//***************************************************************************** +// +// Default queue flush function +// +//***************************************************************************** +am_hal_iom_queue_flush_t am_hal_iom_queue_flush = am_hal_iom_sleeping_queue_flush; + +//***************************************************************************** +// +// Power management structure. +// +//***************************************************************************** +am_hal_iom_pwrsave_t am_hal_iom_pwrsave[AM_REG_IOMSTR_NUM_MODULES]; + + +//***************************************************************************** +// +// Static helper functions +// +//***************************************************************************** + +//***************************************************************************** +// onebit() +//***************************************************************************** +// +// A power of 2? +// Return true if ui32Value has exactly 1 bit set, otherwise false. +// +static bool onebit(uint32_t ui32Value) +{ + return ui32Value && !(ui32Value & (ui32Value - 1)); +} + +//***************************************************************************** +// compute_freq() +//***************************************************************************** +// +// Compute the interface frequency based on the given parameters +// +static uint32_t compute_freq(uint32_t ui32HFRCfreqHz, + uint32_t ui32Fsel, uint32_t ui32Div3, + uint32_t ui32DivEn, uint32_t ui32TotPer) +{ + uint32_t ui32Denomfinal, ui32ClkFreq; + + ui32Denomfinal = ((1 << (ui32Fsel - 1)) * (1 + ui32Div3 * 2) * (1 + ui32DivEn * (ui32TotPer))); + ui32ClkFreq = (ui32HFRCfreqHz) / ui32Denomfinal; // Compute the set frequency value + ui32ClkFreq += (((ui32HFRCfreqHz) % ui32Denomfinal) > (ui32Denomfinal / 2)) ? 1 : 0; + + return ui32ClkFreq; +} + +//***************************************************************************** +// iom_calc_gpio() +// +// Calculate the IOM4 GPIO to assert. +// +//***************************************************************************** +static uint32_t iom_calc_gpio(uint32_t ui32ChipSelect) +{ + uint32_t index; + uint8_t ui8PadRegVal, ui8FncSelVal; + + // + // Figure out which GPIO we are using for the IOM + // + for ( index = 0; index < (sizeof(g_IOMPads) / sizeof(IOMPad_t)); index++ ) + { + // + // Is this one of the CEn that we are using? + // + if ( g_IOMPads[index].channel == ui32ChipSelect ) + { + // + // Get the PAD register value + // + ui8PadRegVal = ((AM_REGVAL(AM_HAL_GPIO_PADREG(g_IOMPads[index].pad))) & + AM_HAL_GPIO_PADREG_M(g_IOMPads[index].pad)) >> + AM_HAL_GPIO_PADREG_S(g_IOMPads[index].pad); + + // + // Get the FNCSEL field value + // + ui8FncSelVal = (ui8PadRegVal & 0x38) >> 3; + + // + // Is the FNCSEL filed for this pad set to the expected value? + // + if ( ui8FncSelVal == g_IOMPads[index].funcsel ) + { + // This is the GPIO we need to use. + return g_IOMPads[index].pad; + } + } + } + return 0xDEADBEEF; +} + +//***************************************************************************** +// +// Checks to see if this processor is a Rev B0 device. +// +// This is needed for the B0 IOM workaround. +// +//***************************************************************************** +bool +isRevB0(void) +{ + // + // Check to make sure the major rev is B and the minor rev is zero. + // + if ( (AM_REG(MCUCTRL, CHIPREV) & 0xFF) == AM_REG_MCUCTRL_CHIPREV_REVMAJ_B ) + { + return true; + } + else + { + return false; + } +} + +//***************************************************************************** +// +//! @brief Returns the proper settings for the CLKCFG register. +//! +//! @param ui32FreqHz - The desired interface frequency in Hz. +//! ui32Phase - SPI phase (0 or 1). Can affect duty cycle. +//! +//! Given a desired serial interface clock frequency, this function computes +//! the appropriate settings for the various fields in the CLKCFG register +//! and returns the 32-bit value that should be written to that register. +//! The actual interface frequency may be slightly lower than the specified +//! frequency, but the actual frequency is also returned. +//! +//! @note A couple of criteria that this algorithm follow are: +//! 1. For power savings, choose the highest FSEL possible. +//! 2. For best duty cycle, use DIV3 when possible rather than DIVEN. +//! +//! An example of #1 is that both of the following CLKCFGs would result +//! in a frequency of 428,571 Hz: 0x0E071400 and 0x1C0E1300. +//! The former is chosen by the algorithm because it results in FSEL=4 +//! while the latter is FSEL=3. +//! +//! An example of #2 is that both of the following CLKCFGs would result +//! in a frequency of 2,000,000 Hz: 0x02011400 and 0x00000C00. +//! The latter is chosen by the algorithm because it results in use of DIV3 +//! rather than DIVEN. +//! +//! @return An unsigned 64-bit value. +//! The lower 32-bits represent the value to use to set CLKCFG. +//! The upper 32-bits represent the actual frequency (in Hz) that will result +//! from setting CLKCFG with the lower 32-bits. +//! +//! 0 (64 bits) = error. Note that the caller must check the entire 64 bits. +//! It is not an error if only the low 32-bits are 0 (this is a valid value). +//! But the entire 64 bits returning 0 is an error. +//! +//***************************************************************************** + +static +uint64_t iom_get_interface_clock_cfg(uint32_t ui32FreqHz, uint32_t ui32Phase ) +{ + uint32_t ui32Fsel, ui32Div3, ui32DivEn, ui32TotPer, ui32LowPer; + uint32_t ui32Denom, ui32v1, ui32Denomfinal, ui32ClkFreq, ui32ClkCfg; + uint32_t ui32HFRCfreqHz; + int32_t i32Div, i32N; + + if ( ui32FreqHz == 0 ) + { + return 0; + } + + // + // Set the HFRC clock frequency. + // + ui32HFRCfreqHz = AM_HAL_CLKGEN_FREQ_MAX_HZ; + + // + // Compute various parameters used for computing the optimal CLKCFG setting. + // + i32Div = (ui32HFRCfreqHz / ui32FreqHz) + ((ui32HFRCfreqHz % ui32FreqHz) ? 1 : 0); // Round up (ceiling) + + // + // Compute N (count the number of LS zeros of Div) = ctz(Div) = log2(Div & (-Div)) + // + i32N = 31 - AM_INSTR_CLZ((i32Div & (-i32Div))); + + if ( i32N > 6 ) + { + i32N = 6; + } + + ui32Div3 = ( (ui32FreqHz < (ui32HFRCfreqHz / 16384)) || + ( ((ui32FreqHz >= (ui32HFRCfreqHz / 3)) && + (ui32FreqHz <= ((ui32HFRCfreqHz / 2) - 1)) ) ) ) ? 1 : 0; + ui32Denom = ( 1 << i32N ) * ( 1 + (ui32Div3 * 2) ); + ui32TotPer = i32Div / ui32Denom; + ui32TotPer += (i32Div % ui32Denom) ? 1 : 0; + ui32v1 = 31 - AM_INSTR_CLZ(ui32TotPer); // v1 = log2(TotPer) + ui32Fsel = (ui32v1 > 7) ? ui32v1 + i32N - 7 : i32N; + ui32Fsel++; + + if ( ui32Fsel > 7 ) + { + // + // This is an error, can't go that low. + // + return 0; + } + + if ( ui32v1 > 7 ) + { + ui32DivEn = ui32TotPer; // Save TotPer for the round up calculation + ui32TotPer = ui32TotPer>>(ui32v1-7); + ui32TotPer += ((ui32DivEn) % (1 << (ui32v1 - 7))) ? 1 : 0; + } + + ui32DivEn = ( (ui32FreqHz >= (ui32HFRCfreqHz / 4)) || + ((1 << (ui32Fsel - 1)) == i32Div) ) ? 0 : 1; + + if (ui32Phase == 1) + { + ui32LowPer = (ui32TotPer - 2) / 2; // Longer high phase + } + else + { + ui32LowPer = (ui32TotPer - 1) / 2; // Longer low phase + } + + ui32ClkCfg = AM_REG_IOMSTR_CLKCFG_FSEL(ui32Fsel) | + AM_REG_IOMSTR_CLKCFG_DIV3(ui32Div3) | + AM_REG_IOMSTR_CLKCFG_DIVEN(ui32DivEn) | + AM_REG_IOMSTR_CLKCFG_LOWPER(ui32LowPer) | + AM_REG_IOMSTR_CLKCFG_TOTPER(ui32TotPer - 1); + + + // + // Now, compute the actual frequency, which will be returned. + // + ui32ClkFreq = compute_freq(ui32HFRCfreqHz, ui32Fsel, ui32Div3, ui32DivEn, ui32TotPer - 1); + + // + // Determine if the actual frequency is a power of 2 (MHz). + // + if ( (ui32ClkFreq % 250000) == 0 ) + { + // + // If the actual clock frequency is a power of 2 ranging from 250KHz up, + // we can simplify the CLKCFG value using DIV3 (which also results in a + // better duty cycle). + // + ui32Denomfinal = ui32ClkFreq / (uint32_t)250000; + + if ( onebit(ui32Denomfinal) ) + { + // + // These configurations can be simplified by using DIV3. Configs + // using DIV3 have a 50% duty cycle, while those from DIVEN will + // have a 66/33 duty cycle. + // + ui32TotPer = ui32LowPer = ui32DivEn = 0; + ui32Div3 = 1; + + // + // Now, compute the return values. + // + ui32ClkFreq = compute_freq(ui32HFRCfreqHz, ui32Fsel, ui32Div3, ui32DivEn, ui32TotPer); + + ui32ClkCfg = AM_REG_IOMSTR_CLKCFG_FSEL(ui32Fsel) | + AM_REG_IOMSTR_CLKCFG_DIV3(1) | + AM_REG_IOMSTR_CLKCFG_DIVEN(0) | + AM_REG_IOMSTR_CLKCFG_LOWPER(0) | + AM_REG_IOMSTR_CLKCFG_TOTPER(0); + } + } + + return ( ((uint64_t)ui32ClkFreq) << 32) | (uint64_t)ui32ClkCfg; + +} //iom_get_interface_clock_cfg() + + +//***************************************************************************** +// +//! @brief Enable the IOM in the power control block. +//! +//! This function enables the desigated IOM module in the power control block. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_pwrctrl_enable(uint32_t ui32Module) +{ + am_hal_debug_assert_msg(ui32Module < AM_REG_IOMSTR_NUM_MODULES, + "Trying to enable an IOM module that doesn't exist."); + + am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_IOM0 << ui32Module); +} + +//***************************************************************************** +// +//! @brief Disable the IOM in the power control block. +//! +//! This function disables the desigated IOM module in the power control block. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_pwrctrl_disable(uint32_t ui32Module) +{ + am_hal_debug_assert_msg(ui32Module < AM_REG_IOMSTR_NUM_MODULES, + "Trying to disable an IOM module that doesn't exist."); + + am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_IOM0 << ui32Module); +} + +//***************************************************************************** +// +//! @brief Enables the IOM module +//! +//! @param ui32Module - The number of the IOM module to be enabled. +//! +//! This function enables the IOM module using the IFCEN bitfield in the +//! IOMSTR_CFG register. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_enable(uint32_t ui32Module) +{ + if ( ui32Module < AM_REG_IOMSTR_NUM_MODULES ) + { + AM_REGn(IOMSTR, ui32Module, CFG) |= AM_REG_IOMSTR_CFG_IFCEN(1); + g_bIomBusy[ui32Module] = false; + } +} + +//***************************************************************************** +// +//! @brief Disables the IOM module. +//! +//! @param ui32Module - The number of the IOM module to be disabled. +//! +//! This function disables the IOM module using the IFCEN bitfield in the +//! IOMSTR_CFG register. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_disable(uint32_t ui32Module) +{ + if ( ui32Module < AM_REG_IOMSTR_NUM_MODULES ) + { + // + // Wait until the bus is idle. + // + am_hal_iom_poll_complete(ui32Module); + + // + // Disable the interface. + // + AM_REGn(IOMSTR, ui32Module, CFG) &= ~(AM_REG_IOMSTR_CFG_IFCEN(1)); + } +} + +//***************************************************************************** +// +//! @brief Enable power to the selected IOM module. +//! +//! @param ui32Module - Module number for the IOM to be turned on. +//! +//! This function enables the power gate to the selected IOM module. It is +//! intended to be used along with am_hal_iom_power_off_save(). Used together, +//! these functions allow the caller to power IOM modules off to save +//! additional power without losing important configuration information. +//! +//! The am_hal_iom_power_off_save() function will save IOM configuration +//! register information to SRAM before powering off the selected IOM module. +//! This function will re-enable the IOM module, and restore those +//! configuration settings from SRAM. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_power_on_restore(uint32_t ui32Module) +{ + am_hal_debug_assert_msg(ui32Module < AM_REG_IOMSTR_NUM_MODULES, + "Trying to enable an IOM module that doesn't exist."); + + // + // Make sure this restore is a companion to a previous save call. + // + if ( am_hal_iom_pwrsave[ui32Module].bValid == 0 ) + { + return; + } + + // + // Enable power to the selected IOM. + // + am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_IOM0 << ui32Module); + + // + // Restore the IOM configuration registers from the structure in SRAM. + // + AM_REGn(IOMSTR, ui32Module, FIFOTHR) = am_hal_iom_pwrsave[ui32Module].FIFOTHR; + AM_REGn(IOMSTR, ui32Module, CLKCFG) = am_hal_iom_pwrsave[ui32Module].CLKCFG; + AM_REGn(IOMSTR, ui32Module, CFG) = am_hal_iom_pwrsave[ui32Module].CFG; + AM_REGn(IOMSTR, ui32Module, INTEN) = am_hal_iom_pwrsave[ui32Module].INTEN; + + // + // Indicates we have restored the configuration. + // + am_hal_iom_pwrsave[ui32Module].bValid = 0; +} + +//***************************************************************************** +// +//! @brief Disable power to the selected IOM module. +//! +//! @param ui32Module - Module number for the IOM to be turned off. +//! +//! This function disables the power gate to the selected IOM module. It is +//! intended to be used along with am_hal_iom_power_on_restore(). Used together, +//! these functions allow the caller to power IOM modules off to save +//! additional power without losing important configuration information. +//! +//! The am_hal_iom_power_off_save() function will save IOM configuration +//! register information to SRAM before powering off the selected IOM module. +//! The am_hal_iom_power_on_restore() function will re-enable the IOM module +//! and restore those configuration settings from SRAM. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_power_off_save(uint32_t ui32Module) +{ + am_hal_debug_assert_msg(ui32Module < AM_REG_IOMSTR_NUM_MODULES, + "Trying to disable an IOM module that doesn't exist."); + + // + // Save the IOM configuration registers to the structure in SRAM. + // + am_hal_iom_pwrsave[ui32Module].FIFOTHR = AM_REGn(IOMSTR, ui32Module, FIFOTHR); + am_hal_iom_pwrsave[ui32Module].CLKCFG = AM_REGn(IOMSTR, ui32Module, CLKCFG); + am_hal_iom_pwrsave[ui32Module].CFG = AM_REGn(IOMSTR, ui32Module, CFG); + am_hal_iom_pwrsave[ui32Module].INTEN = AM_REGn(IOMSTR, ui32Module, INTEN); + + // + // Indicates we have a valid saved configuration. + // + am_hal_iom_pwrsave[ui32Module].bValid = 1; + + // + // Disable power to the selected IOM. + // + am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_IOM0 << ui32Module); +} + +// +//! Check and correct the IOM FIFO threshold. +// +#define MAX_RW_THRESHOLD (AM_HAL_IOM_MAX_FIFO_SIZE - 4) +#define MIN_RW_THRESHOLD (4) +#if (AM_ASSERT_INVALID_THRESHOLD == 0) +static uint8_t check_iom_threshold(const uint8_t iom_threshold) +{ + uint8_t corrected_threshold = iom_threshold; + + if ( corrected_threshold < MIN_RW_THRESHOLD ) + { + corrected_threshold = MIN_RW_THRESHOLD; + } + + if ( corrected_threshold > MAX_RW_THRESHOLD ) + { + corrected_threshold = MAX_RW_THRESHOLD; + } + + return corrected_threshold; +} +#endif + +//***************************************************************************** +// +//! @brief Sets module-wide configuration options for the IOM module. +//! +//! @param ui32Module - The instance number for the module to be configured +//! (zero or one) +//! +//! @param psConfig - Pointer to an IOM configuration structure. +//! +//! This function is used to set the interface mode (SPI or I2C), clock +//! frequency, SPI format (when relevant), and FIFO read/write interrupt +//! thresholds for the IO master. For more information on specific +//! configuration options, please see the documentation for the configuration +//! structure. +//! +//! @note The IOM module should be disabled before configuring or +//! re-configuring. This function will not re-enable the module when it +//! completes. Call the am_hal_iom_enable function when the module is +//! configured and ready to use. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_config(uint32_t ui32Module, const am_hal_iom_config_t *psConfig) +{ + uint32_t ui32Config, ui32ClkCfg; + + // + // Start by checking the interface mode (I2C or SPI), and writing it to the + // configuration word. + // + ui32Config = psConfig->ui32InterfaceMode; + + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + + // + // Check the SPI format, and OR in the bits for SPHA (clock phase) and SPOL + // (polarity). These shouldn't have any effect in I2C mode, so it should be + // ok to write them without checking exactly which mode we're in. + // + if ( psConfig->bSPHA ) + { + ui32Config |= AM_REG_IOMSTR_CFG_SPHA(1); + } + + if ( psConfig->bSPOL ) + { + ui32Config |= AM_REG_IOMSTR_CFG_SPOL(1); + } + + // Set the STARTRD based on the interface speed + // For all I2C frequencies and SPI frequencies below 16 MHz, the STARTRD + // field should be set to 0 to minimize the potential of the IO transfer + // holding off a bus access to the FIFO. For SPI frequencies of 16 MHz + // or 24 MHz, the STARTRD field must be set to a value of 2 to insure + // enough time for the IO preread. + if ( psConfig->ui32ClockFrequency >= 16000000UL) + { + ui32Config |= AM_REG_IOMSTR_CFG_STARTRD(2); + } + + // + // Write the resulting configuration word to the IO master CFG register for + // the module number we were provided. + // + AM_REGn(IOMSTR, ui32Module, CFG) = ui32Config; + + // + // Write the FIFO write and read thresholds to the appropriate registers. + // +#if (AM_ASSERT_INVALID_THRESHOLD == 1) + am_hal_debug_assert_msg( + (psConfig->ui8WriteThreshold <= MAX_RW_THRESHOLD), "IOM write threshold too big."); + am_hal_debug_assert_msg( + (psConfig->ui8ReadThreshold <= MAX_RW_THRESHOLD), "IOM read threshold too big."); + am_hal_debug_assert_msg( + (psConfig->ui8WriteThreshold >= MIN_RW_THRESHOLD), "IOM write threshold too small."); + am_hal_debug_assert_msg( + (psConfig->ui8ReadThreshold >= MIN_RW_THRESHOLD), "IOM read threshold too small."); + + AM_REGn(IOMSTR, ui32Module, FIFOTHR) = + (AM_REG_IOMSTR_FIFOTHR_FIFOWTHR(psConfig->ui8WriteThreshold) | + AM_REG_IOMSTR_FIFOTHR_FIFORTHR(psConfig->ui8ReadThreshold)); +#elif (AM_ASSERT_INVALID_THRESHOLD == 0) + AM_REGn(IOMSTR, ui32Module, FIFOTHR) = + (AM_REG_IOMSTR_FIFOTHR_FIFOWTHR(check_iom_threshold(psConfig->ui8WriteThreshold)) | + AM_REG_IOMSTR_FIFOTHR_FIFORTHR(check_iom_threshold(psConfig->ui8ReadThreshold))); +#else +#error AM_ASSERT_INVALID_THRESHOLD must be 0 or 1. +#endif + + // + // An exception occurs in the LOWPER computation when setting an interface + // frequency (such as a divide by 5 frequency) which results in a 60/40 + // duty cycle. The 60% cycle must occur in the appropriate half-period, + // as only one of the half-periods is active, depending on which phase + // is being selected. + // If SPHA=0 the low period must be 60%. If SPHA=1 high period must be 60%. + // Note that the predetermined frequency parameters use the formula + // lowper = (totper-1)/2, which results in a 60% low period. + // + ui32ClkCfg = iom_get_interface_clock_cfg(psConfig->ui32ClockFrequency, + psConfig->bSPHA ); + if ( ui32ClkCfg ) + { + AM_REGn(IOMSTR, ui32Module, CLKCFG) = (uint32_t)ui32ClkCfg; + } + + // + // Compute the status timeout value. + // + ui32StatusTimeout[ui32Module] = MAX_IOM_BITS * AM_HAL_IOM_MAX_FIFO_SIZE * + IOM_OVERHEAD_FACTOR * (am_hal_clkgen_sysclk_get() / psConfig->ui32ClockFrequency); +} + +//***************************************************************************** +// +//! @brief Returns the actual currently configured interface frequency in Hz. +// +//***************************************************************************** +uint32_t +am_hal_iom_frequency_get(uint32_t ui32ClkCfg) +{ + uint32_t ui32Freq; + + ui32Freq = compute_freq(AM_HAL_CLKGEN_FREQ_MAX_HZ, + (ui32ClkCfg & AM_REG_IOMSTR_CLKCFG_FSEL_M) >> AM_REG_IOMSTR_CLKCFG_FSEL_S, + (ui32ClkCfg & AM_REG_IOMSTR_CLKCFG_DIV3_M) >> AM_REG_IOMSTR_CLKCFG_DIV3_S, + (ui32ClkCfg & AM_REG_IOMSTR_CLKCFG_DIVEN_M) >> AM_REG_IOMSTR_CLKCFG_DIVEN_S, + (ui32ClkCfg & AM_REG_IOMSTR_CLKCFG_TOTPER_M)>> AM_REG_IOMSTR_CLKCFG_TOTPER_S); + + return ui32Freq; +} + +//***************************************************************************** +// +// Helper function for the B0 workaround. +// +//***************************************************************************** +static uint32_t +iom_get_workaround_fsel(uint32_t maxFreq) +{ + uint32_t ui32Freq, ui32Fsel; + uint32_t ui32ClkCfg = AM_REGn(IOMSTR, 4, CLKCFG); + + // + // Starting with the current clock configuration parameters, find a value + // of FSEL that will bring our total frequency down to or below maxFreq. + // + for ( ui32Fsel = 1; ui32Fsel < 8; ui32Fsel++ ) + { + ui32Freq = compute_freq(AM_HAL_CLKGEN_FREQ_MAX_HZ, ui32Fsel, + AM_BFX(IOMSTR, CLKCFG, DIV3, ui32ClkCfg), + AM_BFX(IOMSTR, CLKCFG, DIVEN, ui32ClkCfg), + AM_BFX(IOMSTR, CLKCFG, TOTPER, ui32ClkCfg)); + + if ( ui32Freq <= maxFreq && ui32Freq != 0 ) + { + // + // Return the new FSEL + // + return ui32Fsel; + } + } + + // + // Couldn't find an appropriate frequency. This should be impossible + // because there should always be a value of FSEL that brings the final IOM + // frequency below 500 KHz. + // + am_hal_debug_assert_msg(false, "Could find a valid frequency. Should never get here."); + return maxFreq; +} + +// Separating this piece of code in separate function to keep the impact of +// rest of the code to mimimal because of stack usage +static void +internal_iom_workaround_critical(uint32_t ui32Command, + volatile uint32_t *pui32CSPadreg, + uint32_t ui32CSPadregVal, + uint32_t ui32DelayTime, + uint32_t ui32ClkCfg, + uint32_t ui32LowClkCfg, + bool bRising) +{ + uint32_t ui32Critical = 0; + // + // Start a critical section. + // + ui32Critical = am_hal_interrupt_master_disable(); + + // + // Start the write on the bus. + // + AM_REGn(IOMSTR, WORKAROUND_IOM, CMD) = ui32Command; + + // + // Slow down the clock, and run the workaround loop. The workaround + // loop runs an edge-detector on MOSI, and triggers a falling edge on + // chip-enable on the first bit of our real data. + // + ((void (*)(uint32_t)) 0x0800009d)(ui32DelayTime); + // Switch to Low Freq + AM_REGn(IOMSTR, WORKAROUND_IOM, CLKCFG) = ui32LowClkCfg; + iom_workaround_loop(ui32CSPadregVal, pui32CSPadreg, bRising); + // + // Restore the clock frequency and the normal MOSI pin function. + // + AM_REGn(IOMSTR, WORKAROUND_IOM, CLKCFG) = ui32ClkCfg; + am_hal_gpio_pin_config(WORKAROUND_IOM_MOSI_PIN, WORKAROUND_IOM_MOSI_CFG); + + // + // End the critical section. + // + am_hal_interrupt_master_set(ui32Critical); +} + + +//***************************************************************************** +// +//! @brief Workaround for an Apollo2 Rev B0 issue. +//! +//! @param ui32ChipSelect - Chip-select number for this transaction. +//! @param pui32Data - Pointer to the bytes that will be sent. +//! @param ui32NumBytes - Number of bytes to send. +//! @param ui32Options - Additional SPI transfer options. +//! +//! Some Apollo2 Rev B0 devices have an issue where the first byte of a SPI +//! write transaction can have some of its bits changed from ones to zeroes. In +//! order to get around this issue, we artificially pad the SPI write data with +//! additional bytes, and manually control the CS pin for the beginning of the +//! SPI frame so that the receiving device will ignore the bytes of padding +//! that we added. +//! +//! This function acts as a helper function to higher-level spi APIs. It +//! performs the functions of am_hal_iom_fifo_write() and +//! am_hal_iom_spi_cmd_run() to get a SPI write started on the bus, including +//! all of the necessary workaround behavior. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_workaround_word_write(uint32_t ui32ChipSelect, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options) +{ + uint32_t ui32TransferSize; + uint32_t ui32IOMGPIO = 0xDEADBEEF; + volatile uint32_t *pui32CSPadreg = 0; + uint32_t ui32CSPadregVal = 0; + uint32_t ui32ClkCfg = 0; + uint32_t ui32HiClkCfg, ui32LowClkCfg; + bool bRising = 0; + uint32_t ui32HiFreq = 0, ui32NormalFreq = 0; + uint32_t ui32DelayTime = 0; + uint32_t ui32LowFsel = 0; + uint32_t ui32HiFsel = 0; + uint32_t ui32FirstWord = 0; + uint32_t ui32MaxFifoSize = ((0 == AM_BFRn(IOMSTR, WORKAROUND_IOM, CFG, FULLDUP)) ? + AM_HAL_IOM_MAX_FIFO_SIZE : AM_HAL_IOM_MAX_FIFO_SIZE / 2); + uint32_t ui32Command; + // + // Make sure the transfer isn't too long for the hardware to support. + // + // Note: This is a little shorter than usual, since the workaround + // consumes an extra byte at the beginning of the transfer. + // + am_hal_debug_assert_msg(ui32NumBytes <= 4091, "SPI transfer too big."); + + // + // Create a "dummy" word to add on to the beginning of the transfer + // that will guarantee a transition between the first word and the + // second on the bus. + // + // For raw transactions, this is straightforward. For transactions + // preceded by an offset, we'll add the offset in to the "dummy" word + // to preserve data alignment later. + // + // The workaround uses a critical section for precision + // To minimize the time in critical section, we raise the SPI frequency + // to the max possible for the initial preamble to be clocked out + // then we switch to a 'reasonably' slow frequency to be able to reliably + // catch the rising or falling edge by polling. Then we switch back to + // configured frequency + // + + // We want to slow down the clock to help us count edges more + // accurately. Save it first, then slow it down. Also, we will + // pre-calculate a delay for when we need to restore the SPI settings. + // + ui32ClkCfg = AM_REGn(IOMSTR, WORKAROUND_IOM, CLKCFG); + // Get the largest speed we can configure within our rated speed of 16MHz + ui32HiFsel = iom_get_workaround_fsel(16000000); + ui32HiClkCfg = ((ui32ClkCfg & (~AM_REG_IOMSTR_CLKCFG_FSEL_M)) | + AM_BFV(IOMSTR, CLKCFG, FSEL, ui32HiFsel)); + // Switch to Hi Freq + // Need to make sure we wait long enough for the hi clock to be effective + // Delay 2 cycles based on previous frequency + ui32NormalFreq = am_hal_iom_frequency_get(ui32ClkCfg); + AM_REGn(IOMSTR, WORKAROUND_IOM, CLKCFG) = ui32HiClkCfg; + ui32DelayTime = ((2 * AM_HAL_CLKGEN_FREQ_MAX_HZ) / (ui32NormalFreq * 3)); + ((void (*)(uint32_t)) 0x0800009d)(ui32DelayTime); + // + // Remember what frequency we'll be running at.during Hi Phase + // + ui32HiFreq = am_hal_iom_frequency_get(ui32HiClkCfg); + + // + // Validate return value to prevent DIVBY0 errors. + // + am_hal_debug_assert_msg(ui32HiFreq > 0, "Invalid Hi Frequency for IOM."); + + // Get a reasonably slow speed (~1MHz) we can safely poll for the transition + ui32LowFsel = iom_get_workaround_fsel(1000000); + ui32LowClkCfg = ((ui32ClkCfg & (~AM_REG_IOMSTR_CLKCFG_FSEL_M)) | + AM_BFV(IOMSTR, CLKCFG, FSEL, ui32LowFsel)); + + if ( ui32Options & AM_HAL_IOM_RAW ) + { + // + // The transition we care for is on 33rd bit. + // Prepare to delay 27 bits past the start of the transaction + // before getting into polling - to leave some + // margin for compiler related variations + // + ui32DelayTime = ((27 * AM_HAL_CLKGEN_FREQ_MAX_HZ) / (ui32HiFreq * 3)); + + if ( pui32Data[0] & 0x80 ) + { + ui32FirstWord = 0x00000000; + bRising = true; + } + else + { + ui32FirstWord = 0xFFFFFF00; + bRising = false; + } + } + else + { + // + // The transition we care for is on 25th bit. + // Prepare to delay 19 bits past the start of the transaction + // before getting into polling - to leave some + // margin for compiler related variations + // + ui32DelayTime = ((19 * AM_HAL_CLKGEN_FREQ_MAX_HZ) / (ui32HiFreq * 3)); + ui32FirstWord = ((ui32Options & 0xFF00) << 16); + if ( ui32FirstWord & 0x80000000 ) + { + bRising = true; + } + else + { + ui32FirstWord |= 0x00FFFF00; + bRising = false; + } + } + + // + // Now that weve taken care of the offset byte, we can run the + // transaction in RAW mode. + // + ui32Options |= AM_HAL_IOM_RAW; + + ui32NumBytes += 4; + + // + // Figure out how many bytes we can write to the FIFO immediately. + // + ui32TransferSize = (ui32NumBytes <= ui32MaxFifoSize ? ui32NumBytes : + ui32MaxFifoSize); + + am_hal_iom_fifo_write(WORKAROUND_IOM, &ui32FirstWord, 4); + + am_hal_iom_fifo_write(WORKAROUND_IOM, pui32Data, ui32TransferSize - 4); + + // + // Calculate the GPIO to be controlled until the initial shift is + // complete. Make sure we get a valid value. + // + ui32IOMGPIO = iom_calc_gpio(ui32ChipSelect); + am_hal_debug_assert(0xDEADBEEF != ui32IOMGPIO); + + // + // Save the locations and values of the CS pin configuration + // information. + // + pui32CSPadreg = (volatile uint32_t *)AM_HAL_GPIO_PADREG(ui32IOMGPIO); + ui32CSPadregVal = *pui32CSPadreg; + + // + // Switch CS to a GPIO. + // + am_hal_gpio_out_bit_set(ui32IOMGPIO); + am_hal_gpio_pin_config(ui32IOMGPIO, AM_HAL_GPIO_OUTPUT); + + // + // Enable the input buffer on MOSI. + // + am_hal_gpio_pin_config(WORKAROUND_IOM_MOSI_PIN, WORKAROUND_IOM_MOSI_CFG | AM_HAL_PIN_DIR_INPUT); + + // + // Write the GPIO PADKEY register to allow the workaround loop to + // reconfigure chip enable. + // + AM_REGn(GPIO, 0, PADKEY) = AM_REG_GPIO_PADKEY_KEYVAL; + // Preconstruct the command - to save on calculations inside critical section + ui32Command = internal_am_hal_iom_spi_cmd_construct(AM_HAL_IOM_WRITE, + ui32ChipSelect, ui32NumBytes, ui32Options); + internal_iom_workaround_critical(ui32Command, + pui32CSPadreg, ui32CSPadregVal, + ui32DelayTime, ui32ClkCfg, + ui32LowClkCfg, bRising); + + // + // Update the pointer and data counter. + // + ui32NumBytes -= ui32TransferSize; + pui32Data += (ui32TransferSize - 4) >> 2; +} + +//***************************************************************************** +// +//! @brief Implement an iterative spin loop. +//! +//! @param ui32Iterations - Number of iterations to delay. +//! +//! Use this function to implement a CPU busy waiting spin. For Apollo, this +//! delay can be used for timing purposes since for Apollo, each iteration will +//! take 3 cycles. +//! +//! @return None. +// +//***************************************************************************** +#if defined(__GNUC_STDC_INLINE__) +static void __attribute__((naked)) +iom_workaround_loop(uint32_t ui32PadRegVal, volatile uint32_t *pui32PadReg, + bool bRising) +{ + // + // Check to see if this is a "rising edge" or "falling edge" detector. + // + __asm(" cbz r2, falling_edge"); + + // + // Read GPIO pin 44, and loop until it's HIGH. + // + __asm("rising_edge:"); + __asm(" ldr r2, =0x40010084"); + __asm("rising_check_mosi:"); + __asm(" ldr r3, [r2]"); + __asm(" ands r3, r3, #0x1000"); + __asm(" beq rising_check_mosi"); + + // + // Write the PADREG Value to the PADREG register. + // + __asm(" str r0, [r1]"); + __asm(" bx lr"); + + // + // Read GPIO pin 44, and loop until it's LOW. + // + __asm("falling_edge:"); + __asm(" ldr r2, =0x40010084"); + __asm("falling_check_mosi:"); + __asm(" ldr r3, [r2]"); + __asm(" ands r3, r3, #0x1000"); + __asm(" bne falling_check_mosi"); + + // + // Write the PADREG Value to the PADREG register. + // + __asm(" str r0, [r1]"); + __asm(" bx lr"); +} +#endif +#ifdef keil +__asm static void +iom_workaround_loop(uint32_t ui32PadRegVal, volatile uint32_t *pui32PadReg, + bool bRising) +{ + // + // Check to see if this is a "rising edge" or "falling edge" detector. + // + cbz r2, falling_edge + + // + // Read GPIO pin 44, and loop until it's HIGH. + // +rising_edge + ldr r2, =0x40010084 +rising_check_mosi + ldr r3, [r2] + ands r3, r3, #0x1000 + beq rising_check_mosi + + // + // Write the PADREG Value to the PADREG register. + // + str r0, [r1] + bx lr + + // + // Read GPIO pin 44, and loop until it's LOW. + // +falling_edge + ldr r2, =0x40010084 +falling_check_mosi + ldr r3, [r2] + ands r3, r3, #0x1000 + bne falling_check_mosi + + // + // Write the PADREG Value to the PADREG register. + // + str r0, [r1] + bx lr + nop +} +#endif +#ifdef iar +static void +iom_workaround_loop(uint32_t ui32PadRegVal, volatile uint32_t *pui32PadReg, + bool bRising) +{ + // + // Check to see if this is a "rising edge" or "falling edge" detector. + // + asm( + " cbz r2, falling_edge\n" + + // + // Read GPIO pin 44, and loop until it's HIGH. + // + "rising_edge:\n" + " mov32 r2, #0x40010084\n" + "rising_check_mosi:\n" + " ldr r3, [r2]\n" + " ands r3, r3, #0x1000\n" + " beq rising_check_mosi\n" + + // + // Write the PADREG Value to the PADREG register. + // + " str r0, [r1]\n" + " bx lr\n" + + // + // Read GPIO pin 44, and loop until it's LOW. + // + "falling_edge:\n" + " mov32 r2, #0x40010084\n" + "falling_check_mosi:\n" + " ldr r3, [r2]\n" + " ands r3, r3, #0x1000\n" + " bne falling_check_mosi\n" + + // + // Write the PADREG Value to the PADREG register. + // + " str r0, [r1]\n" + " bx lr" + ); +} +#endif + +//***************************************************************************** +// +//! @brief Perform a simple write to the SPI interface. +//! +//! @param ui32Module - Module number for the IOM +//! @param ui32ChipSelect - Chip-select number for this transaction. +//! @param pui32Data - Pointer to the bytes that will be sent. +//! @param ui32NumBytes - Number of bytes to send. +//! @param ui32Options - Additional SPI transfer options. +//! +//! This function performs SPI writes to a selected SPI device. +//! +//! @note The actual SPI and I2C interfaces operate in BYTES, not 32-bit words. +//! This means that you will need to byte-pack the \e pui32Data array with the +//! data you intend to send over the interface. One easy way to do this is to +//! declare the array as a 32-bit integer array, but use an 8-bit pointer to +//! put your actual data into the array. If there are not enough bytes in your +//! desired message to completely fill the last 32-bit word, you may pad that +//! last word with bytes of any value. The IOM hardware will only read the +//! first \e ui32NumBytes in the \e pui8Data array. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_spi_write(uint32_t ui32Module, uint32_t ui32ChipSelect, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options) +{ + // + // Validate parameters + // + am_hal_debug_assert_msg(ui32Module < AM_REG_IOMSTR_NUM_MODULES, + "Trying to use an IOM module that doesn't exist."); + am_hal_debug_assert_msg(ui32NumBytes > 0, + "Trying to do a 0 byte transaction"); + + // + // Check to see if queues have been enabled. If they are, we'll actually + // switch to the queued interface. + // + if ( g_psIOMQueue[ui32Module].pui8Data != NULL ) + { + // + // If the queue is on, go ahead and add this transaction to the queue. + // + am_hal_iom_queue_spi_write(ui32Module, ui32ChipSelect, pui32Data, + ui32NumBytes, ui32Options, 0); + + // + // Wait until the transaction actually clears. + // + am_hal_iom_queue_flush(ui32Module); + + // + // At this point, we've completed the transaction, and we can return. + // + return; + } + else + { + // + // Otherwise, we'll just do a polled transaction. + // + am_hal_iom_spi_write_nq(ui32Module, ui32ChipSelect, pui32Data, + ui32NumBytes, ui32Options); + } +} + +//***************************************************************************** +// +//! @brief Perform simple SPI read operations. +//! +//! @param ui32Module - Module number for the IOM +//! @param ui32ChipSelect - Chip-select number for this transaction. +//! @param pui32Data - Pointer to the array where received bytes should go. +//! @param ui32NumBytes - Number of bytes to read. +//! @param ui32Options - Additional SPI transfer options. +//! +//! This function performs simple SPI read operations. The caller is +//! responsible for ensuring that the receive buffer is large enough to hold +//! the requested amount of data. +//! +//! @note The actual SPI and I2C interfaces operate in BYTES, not 32-bit words. +//! This function will pack the individual bytes from the physical interface +//! into 32-bit words, which are then placed into the \e pui32Data array. Only +//! the first \e ui32NumBytes bytes in this array will contain valid data. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_spi_read(uint32_t ui32Module, uint32_t ui32ChipSelect, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options) +{ + // + // Validate parameters + // + am_hal_debug_assert_msg(ui32Module < AM_REG_IOMSTR_NUM_MODULES, + "Trying to use an IOM module that doesn't exist."); + am_hal_debug_assert_msg(ui32NumBytes > 0, + "Trying to do a 0 byte transaction"); + + // + // Make sure the transfer isn't too long for the hardware to support. + // + am_hal_debug_assert_msg(ui32NumBytes < 4096, "SPI transfer too big."); + + // + // Check to see if queues have been enabled. If they are, we'll actually + // switch to the queued interface. + // + if ( g_psIOMQueue[ui32Module].pui8Data != NULL ) + { + // + // If the queue is on, go ahead and add this transaction to the queue. + // + am_hal_iom_queue_spi_read(ui32Module, ui32ChipSelect, pui32Data, + ui32NumBytes, ui32Options, 0); + + // + // Wait until the transaction actually clears. + // + am_hal_iom_queue_flush(ui32Module); + + // + // At this point, we've completed the transaction, and we can return. + // + return; + } + else + { + // + // Otherwise, just perform a polled transaction. + // + am_hal_iom_spi_read_nq(ui32Module, ui32ChipSelect, pui32Data, + ui32NumBytes, ui32Options); + } +} + +//***************************************************************************** +// +//! @brief Perform a simple write to the SPI interface (without queuing) +//! +//! @param ui32Module - Module number for the IOM +//! @param ui32ChipSelect - Chip-select number for this transaction. +//! @param pui32Data - Pointer to the bytes that will be sent. +//! @param ui32NumBytes - Number of bytes to send. +//! @param ui32Options - Additional SPI transfer options. +//! +//! This function performs SPI writes to a selected SPI device. +//! +//! @note The actual SPI and I2C interfaces operate in BYTES, not 32-bit words. +//! This means that you will need to byte-pack the \e pui32Data array with the +//! data you intend to send over the interface. One easy way to do this is to +//! declare the array as a 32-bit integer array, but use an 8-bit pointer to +//! put your actual data into the array. If there are not enough bytes in your +//! desired message to completely fill the last 32-bit word, you may pad that +//! last word with bytes of any value. The IOM hardware will only read the +//! first \e ui32NumBytes in the \e pui8Data array. +//! +//! @return None. +// +//***************************************************************************** +uint32_t +am_hal_iom_spi_write_nq(uint32_t ui32Module, uint32_t ui32ChipSelect, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options) +{ + uint32_t ui32TransferSize; + uint32_t ui32SpaceInFifo; + uint32_t ui32IntConfig; + uint32_t ui32MaxFifoSize; + uint32_t ui32Status = 1; + + // + // Validate parameters + // + am_hal_debug_assert_msg(ui32Module < AM_REG_IOMSTR_NUM_MODULES, + "Trying to use an IOM module that doesn't exist."); + am_hal_debug_assert_msg(ui32NumBytes > 0, + "Trying to do a 0 byte transaction"); + + // + // Make sure the transfer isn't too long for the hardware to support. + // + am_hal_debug_assert_msg(ui32NumBytes < 4096, "SPI transfer too big."); + + ui32MaxFifoSize = ((0 == AM_BFRn(IOMSTR, ui32Module, CFG, FULLDUP)) ? + AM_HAL_IOM_MAX_FIFO_SIZE : AM_HAL_IOM_MAX_FIFO_SIZE / 2); + // + // Wait until any earlier transactions have completed. + // + am_hal_iom_poll_complete(ui32Module); + // + // Disable interrupts so that we don't get any undesired interrupts. + // + ui32IntConfig = AM_REGn(IOMSTR, ui32Module, INTEN); + AM_REGn(IOMSTR, ui32Module, INTEN) = 0; + // Clear CMDCMP status + AM_BFWn(IOMSTR, ui32Module, INTCLR, CMDCMP, 1); + + // + // If we're on a B0 part, and we're using IOM4, our first byte coule be + // corrupted, so we need to send a dummy word with chip-select held high to + // get that first byte out of the way. + // + // That operation is tricky and detailed, so we'll call a function to do it + // for us. + // + if ( WORKAROUND_IOM == ui32Module && isRevB0() ) + { + am_hal_iom_workaround_word_write(ui32ChipSelect, pui32Data, + ui32NumBytes, ui32Options); + // + // The workaround function is going to a partial transfer for us, but + // we have to keep our own data-tracking variables updated. Here, we're + // subtracting 4 bytes from the effective transfer size to account for + // the 4 bytes of "dummy" word that we sent instead of the actual data. + // + ui32TransferSize = (ui32NumBytes <= (ui32MaxFifoSize - 4) ? ui32NumBytes : + (ui32MaxFifoSize - 4)); + } + else + { + // + // Figure out how many bytes we can write to the FIFO immediately. + // + ui32TransferSize = (ui32NumBytes <= ui32MaxFifoSize ? ui32NumBytes : + ui32MaxFifoSize); + // + // write our first word to the fifo. + // + + am_hal_iom_fifo_write(ui32Module, pui32Data, ui32TransferSize); + + // + // Start the write on the bus. + // + am_hal_iom_spi_cmd_run(AM_HAL_IOM_WRITE, ui32Module, ui32ChipSelect, + ui32NumBytes, ui32Options); + } + + // + // Update the pointer and data counter. + // + ui32NumBytes -= ui32TransferSize; + pui32Data += ui32TransferSize >> 2; + + // + // Keep looping until we're out of bytes to send or command complete (error). + // + while ( ui32NumBytes && !AM_BFRn(IOMSTR, ui32Module, INTSTAT, CMDCMP) ) + { + // + // This will always return a multiple of four. + // + ui32SpaceInFifo = am_hal_iom_fifo_empty_slots(ui32Module); + + if ( ui32NumBytes <= ui32SpaceInFifo ) + { + // + // If the entire message will fit in the fifo, prepare to copy + // everything. + // + ui32TransferSize = ui32NumBytes; + } + else + { + // + // If only a portion of the message will fit in the fifo, prepare + // to copy the largest number of 4-byte blocks possible. + // + ui32TransferSize = ui32SpaceInFifo & ~(0x3); + } + + // + // Write this chunk to the fifo. + // + am_hal_iom_fifo_write(ui32Module, pui32Data, ui32TransferSize); + + // + // Update the data pointer and bytes-left count. + // + ui32NumBytes -= ui32TransferSize; + pui32Data += ui32TransferSize >> 2; + } + + // + // Make sure CMDCMP was raised with standard timeout + // + ui32Status = am_util_wait_status_change(ui32StatusTimeout[ui32Module], + AM_REG_IOMSTRn(ui32Module) + AM_REG_IOMSTR_INTSTAT_O, + AM_REG_IOMSTR_INTEN_CMDCMP_M, AM_REG_IOMSTR_INTEN_CMDCMP_M); + + // + // Re-enable IOM interrupts. Make sure CMDCMP is cleared + // + AM_REGn(IOMSTR, ui32Module, INTCLR) = (ui32IntConfig | AM_REG_IOMSTR_INTSTAT_CMDCMP_M); + AM_REGn(IOMSTR, ui32Module, INTEN) = ui32IntConfig; + + am_hal_debug_assert_msg(ui32Status == 1,"IOM CMDCMP was not seen"); + + // + // Return the status (0 = timeout; 1 = success) + // + return ui32Status; + +} + +//***************************************************************************** +// +//! @brief Perform simple SPI read operations (without queuing). +//! +//! @param ui32Module - Module number for the IOM +//! @param ui32ChipSelect - Chip-select number for this transaction. +//! @param pui32Data - Pointer to the array where received bytes should go. +//! @param ui32NumBytes - Number of bytes to read. +//! @param ui32Options - Additional SPI transfer options. +//! +//! This function performs simple SPI read operations. The caller is +//! responsible for ensuring that the receive buffer is large enough to hold +//! the requested amount of data. +//! +//! @note The actual SPI and I2C interfaces operate in BYTES, not 32-bit words. +//! This function will pack the individual bytes from the physical interface +//! into 32-bit words, which are then placed into the \e pui32Data array. Only +//! the first \e ui32NumBytes bytes in this array will contain valid data. +//! +//! @return None. +// +//***************************************************************************** +uint32_t +am_hal_iom_spi_read_nq(uint32_t ui32Module, uint32_t ui32ChipSelect, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options) +{ + uint32_t ui32BytesInFifo; + uint32_t ui32IntConfig; + uint32_t bCmdCmp = false; + uint32_t ui32Status = 1; + + // + // Validate parameters + // + am_hal_debug_assert_msg(ui32Module < AM_REG_IOMSTR_NUM_MODULES, + "Trying to use an IOM module that doesn't exist."); + am_hal_debug_assert_msg(ui32NumBytes > 0, + "Trying to do a 0 byte transaction"); + + // + // Make sure the transfer isn't too long for the hardware to support. + // + am_hal_debug_assert_msg(ui32NumBytes < 4096, "SPI transfer too big."); + + // + // Wait until the bus is idle, then start the requested READ transfer on + // the physical interface. + // + am_hal_iom_poll_complete(ui32Module); + + // + // Disable interrupts so that we don't get any undesired interrupts. + // + ui32IntConfig = AM_REGn(IOMSTR, ui32Module, INTEN); + + // + // Disable IOM interrupts as we'll be polling + // + AM_REGn(IOMSTR, ui32Module, INTEN) = 0; + + // + // Clear CMDCMP status + // + AM_BFWn(IOMSTR, ui32Module, INTCLR, CMDCMP, 1); + + // + // If we're on a B0 part, and we're using IOM4, our first byte coule be + // corrupted, so we need to send a dummy word with chip-select held high to + // get that first byte out of the way. This is only true for spi reads with + // OFFSET values. + // + // That operation is tricky and detailed, so we'll call a function to do it + // for us. + // + if ( (WORKAROUND_IOM == ui32Module) && !(ui32Options & AM_HAL_IOM_RAW) && + isRevB0() ) + { + am_hal_iom_workaround_word_write(ui32ChipSelect, pui32Data, 0, + ui32Options | AM_HAL_IOM_CS_LOW); + + // + // The workaround will send our offset for us, so we can run a RAW + // command after. + // + ui32Options |= AM_HAL_IOM_RAW; + // + // Wait for the dummy word to go out over the bus. + // + // Make sure the command complete has also been raised + ui32Status = am_util_wait_status_change(ui32StatusTimeout[ui32Module], + AM_REG_IOMSTRn(ui32Module) + AM_REG_IOMSTR_INTSTAT_O, + AM_REG_IOMSTR_INTEN_CMDCMP_M, AM_REG_IOMSTR_INTEN_CMDCMP_M); + + + // Clear CMDCMP status + AM_BFWn(IOMSTR, ui32Module, INTCLR, CMDCMP, 1); + } + + am_hal_iom_spi_cmd_run(AM_HAL_IOM_READ, ui32Module, ui32ChipSelect, + ui32NumBytes, ui32Options); + + // + // Start a loop to catch the Rx data. + // + while ( ui32NumBytes ) + { + ui32BytesInFifo = am_hal_iom_fifo_full_slots(ui32Module); + + if ( ui32BytesInFifo >= ui32NumBytes ) + { + // + // If the fifo contains our entire message, just copy the whole + // thing out. + // + am_hal_iom_fifo_read(ui32Module, pui32Data, ui32NumBytes); + ui32NumBytes = 0; + } + else if ( ui32BytesInFifo >= 4 ) + { + // + // If the fifo has at least one 32-bit word in it, copy whole + // words out. + // + am_hal_iom_fifo_read(ui32Module, pui32Data, ui32BytesInFifo & ~0x3); + ui32NumBytes -= ui32BytesInFifo & ~0x3; + pui32Data += ui32BytesInFifo >> 2; + } + if ( bCmdCmp == true ) + { + // + // No more data expected. Get out of the loop + // + break; + } + + bCmdCmp = AM_BFRn(IOMSTR, ui32Module, INTSTAT, CMDCMP); + } + + // + // Make sure CMDCMP was raised, + // + ui32Status = am_util_wait_status_change(ui32StatusTimeout[ui32Module], + AM_REG_IOMSTRn(ui32Module) + AM_REG_IOMSTR_INTSTAT_O, + AM_REG_IOMSTR_INTEN_CMDCMP_M, AM_REG_IOMSTR_INTEN_CMDCMP_M); + + // + // Re-enable IOM interrupts. Make sure CMDCMP is cleared + // + AM_REGn(IOMSTR, ui32Module, INTCLR) = (ui32IntConfig | AM_REG_IOMSTR_INTSTAT_CMDCMP_M); + AM_REGn(IOMSTR, ui32Module, INTEN) = ui32IntConfig; + + am_hal_debug_assert_msg(ui32Status == 1,"IOM CMDCMP was not seen"); + + // + // Return the status (0 = timeout; 1 = success) + // + return ui32Status; +} + +//***************************************************************************** +// +//! @brief Perform a non-blocking write to the SPI interface. +//! +//! @param ui32Module - Module number for the IOM +//! @param ui32ChipSelect - Chip-select number for this transaction. +//! @param pui32Data - Pointer to the bytes that will be sent. +//! @param ui32NumBytes - Number of bytes to send. +//! @param ui32Options - Additional SPI transfer options. +//! @param pfnCallback - Function to call when the transaction completes. +//! +//! This function performs SPI writes to the selected SPI device. +//! +//! This function call is a non-blocking implementation. It will write as much +//! data to the FIFO as possible immediately, store a pointer to the remaining +//! data, start the transfer on the bus, and then immediately return. The +//! caller will need to make sure that \e am_hal_iom_int_service() is called +//! for IOM FIFO interrupt events and "command complete" interrupt events. The +//! \e am_hal_iom_int_service() function will refill the FIFO as necessary and +//! call the \e pfnCallback function when the transaction is finished. +//! +//! @note The actual SPI and I2C interfaces operate in BYTES, not 32-bit words. +//! This means that you will need to byte-pack the \e pui32Data array with the +//! data you intend to send over the interface. One easy way to do this is to +//! declare the array as a 32-bit integer array, but use an 8-bit pointer to +//! put your actual data into the array. If there are not enough bytes in your +//! desired message to completely fill the last 32-bit word, you may pad that +//! last word with bytes of any value. The IOM hardware will only read the +//! first \e ui32NumBytes in the \e pui8Data array. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_spi_write_nb(uint32_t ui32Module, uint32_t ui32ChipSelect, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options, + am_hal_iom_callback_t pfnCallback) +{ + uint32_t ui32TransferSize; + uint32_t ui32MaxFifoSize; + + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + + // + // Make sure the transfer isn't too long for the hardware to support. + // + am_hal_debug_assert_msg(ui32NumBytes < 4096, "SPI transfer too big."); + am_hal_debug_assert_msg(ui32NumBytes > 0, + "Trying to do a 0 byte transaction"); + + ui32MaxFifoSize = ((0 == AM_BFRn(IOMSTR, ui32Module, CFG, FULLDUP)) ? + AM_HAL_IOM_MAX_FIFO_SIZE : AM_HAL_IOM_MAX_FIFO_SIZE / 2); + + // + // Wait until the bus is idle + // + am_hal_iom_poll_complete(ui32Module); + + // + // Need to mark IOM busy to avoid another transaction to be scheduled. + // This is to take care of a race condition in Queue mode, where the IDLE + // set is not a guarantee that the CMDCMP has been received + // + g_bIomBusy[ui32Module] = true; + + // + // Clear CMDCMP status + // + AM_BFWn(IOMSTR, ui32Module, INTCLR, CMDCMP, 1); + + // + // Check to see if we need to do the workaround. + // + if ( WORKAROUND_IOM == ui32Module && isRevB0() ) + { + // + // Figure out how many bytes we can write to the FIFO immediately, + // accounting for the extra word from the workaround. + // + ui32TransferSize = (ui32NumBytes <= (ui32MaxFifoSize - 4) ? ui32NumBytes : + (ui32MaxFifoSize - 4)); + + // + // Prepare the global IOM buffer structure. + // + g_psIOMBuffers[ui32Module].ui32State = BUFFER_SENDING; + g_psIOMBuffers[ui32Module].pui32Data = pui32Data + (ui32TransferSize / 4); + g_psIOMBuffers[ui32Module].ui32BytesLeft = ui32NumBytes - ui32TransferSize; + g_psIOMBuffers[ui32Module].pfnCallback = pfnCallback; + g_psIOMBuffers[ui32Module].ui32Options = ui32Options; + + // + // Start the write on the bus using the workaround. This includes both + // the command write and the first fifo write, so we won't need to do + // either of those things manually. + // + am_hal_iom_workaround_word_write(ui32ChipSelect, pui32Data, + ui32NumBytes, ui32Options); + } + else + { + // + // Figure out how many bytes we can write to the FIFO immediately. + // + ui32TransferSize = (ui32NumBytes <= ui32MaxFifoSize ? ui32NumBytes : + ui32MaxFifoSize); + + if ( am_hal_iom_fifo_write(ui32Module, pui32Data, ui32TransferSize) > 0 ) + { + // + // Prepare the global IOM buffer structure. + // + g_psIOMBuffers[ui32Module].ui32State = BUFFER_SENDING; + g_psIOMBuffers[ui32Module].pui32Data = pui32Data; + g_psIOMBuffers[ui32Module].ui32BytesLeft = ui32NumBytes; + g_psIOMBuffers[ui32Module].pfnCallback = pfnCallback; + g_psIOMBuffers[ui32Module].ui32Options = ui32Options; + + // + // Update the pointer and the byte counter based on the portion of + // the transfer we just sent to the fifo. + // + g_psIOMBuffers[ui32Module].ui32BytesLeft -= ui32TransferSize; + g_psIOMBuffers[ui32Module].pui32Data += (ui32TransferSize / 4); + + // + // Start the write on the bus. + // + am_hal_iom_spi_cmd_run(AM_HAL_IOM_WRITE, ui32Module, ui32ChipSelect, + ui32NumBytes, ui32Options); + } + } +} + +//***************************************************************************** +// +//! @brief Perform a non-blocking SPI read. +//! +//! @param ui32Module - Module number for the IOM. +//! @param ui32ChipSelect - Chip select number of the target device. +//! @param pui32Data - Pointer to the array where received bytes should go. +//! @param ui32NumBytes - Number of bytes to read. +//! @param ui32Options - Additional SPI transfer options. +//! @param pfnCallback - Function to call when the transaction completes. +//! +//! This function performs SPI reads to a selected SPI device. +//! +//! This function call is a non-blocking implementation. It will start the SPI +//! transaction on the bus and store a pointer for the destination for the read +//! data, but it will not wait for the SPI transaction to finish. The caller +//! will need to make sure that \e am_hal_iom_int_service() is called for IOM +//! FIFO interrupt events and "command complete" interrupt events. The \e +//! am_hal_iom_int_service() function will empty the FIFO as necessary, +//! transfer the data to the \e pui32Data buffer, and call the \e pfnCallback +//! function when the transaction is finished. +//! +//! @note The actual SPI and I2C interfaces operate in BYTES, not 32-bit words. +//! This function will pack the individual bytes from the physical interface +//! into 32-bit words, which are then placed into the \e pui32Data array. Only +//! the first \e ui32NumBytes bytes in this array will contain valid data. +//! +//! @return None. +// +//***************************************************************************** +uint32_t +am_hal_iom_spi_read_nb(uint32_t ui32Module, uint32_t ui32ChipSelect, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options, + am_hal_iom_callback_t pfnCallback) +{ + uint32_t ui32IntConfig; + uint32_t ui32Status = 1; + + // + // Validate parameters + // + am_hal_debug_assert_msg(ui32Module < AM_REG_IOMSTR_NUM_MODULES, + "Trying to use an IOM module that doesn't exist."); + am_hal_debug_assert_msg(ui32NumBytes > 0, + "Trying to do a 0 byte transaction"); + + // + // Make sure the transfer isn't too long for the hardware to support. + // + am_hal_debug_assert_msg(ui32NumBytes < 4096, "SPI transfer too big."); + + // + // Wait until the bus is idle + // + am_hal_iom_poll_complete(ui32Module); + + // + // Need to mark IOM busy to avoid another transaction to be scheduled. + // This is to take care of a race condition in Queue mode, where the IDLE + // set is not a guarantee that the CMDCMP has been received + // + + g_bIomBusy[ui32Module] = true; + + // + // Clear CMDCMP status + // + AM_BFWn(IOMSTR, ui32Module, INTCLR, CMDCMP, 1); + + // + // If we're on a B0 part, and we're using IOM4, our first byte coule be + // corrupted, so we need to send a dummy word with chip-select held high to + // get that first byte out of the way. This is only true for spi reads with + // OFFSET values. + // + // That operation is tricky and detailed, so we'll call a function to do it + // for us. + // + if ( (WORKAROUND_IOM == ui32Module) && !(ui32Options & AM_HAL_IOM_RAW) && + isRevB0() ) + { + // + // We might mess up the interrupt handler behavior if we allow this + // polled transaction to complete with interrupts enabled. We'll + // briefly turn them off here. + // + ui32IntConfig = AM_REGn(IOMSTR, 4, INTEN); + AM_REGn(IOMSTR, 4, INTEN) = 0; + + am_hal_iom_workaround_word_write(ui32ChipSelect, pui32Data, + 0, ui32Options | AM_HAL_IOM_CS_LOW); + + // + // The workaround will send our offset for us, so we can run a RAW + // command after. + // + ui32Options |= AM_HAL_IOM_RAW; + + // + // Wait for the dummy word to go out over the bus. + // + // Make sure the command complete has also been raised + ui32Status = am_util_wait_status_change(ui32StatusTimeout[ui32Module], + AM_REG_IOMSTRn(ui32Module) + AM_REG_IOMSTR_INTSTAT_O, + AM_REG_IOMSTR_INTEN_CMDCMP_M, AM_REG_IOMSTR_INTEN_CMDCMP_M); + + // + // Re-mark IOM as busy + // + + g_bIomBusy[ui32Module] = true; + + // + // Re-enable IOM interrupts. Make sure CMDCMP is cleared + // + AM_REGn(IOMSTR, 4, INTCLR) = (ui32IntConfig | AM_REG_IOMSTR_INTSTAT_CMDCMP_M); + AM_REGn(IOMSTR, 4, INTEN) = ui32IntConfig; + } + + // + // Prepare the global IOM buffer structure. + // + g_psIOMBuffers[ui32Module].ui32State = BUFFER_RECEIVING; + g_psIOMBuffers[ui32Module].pui32Data = pui32Data; + g_psIOMBuffers[ui32Module].ui32BytesLeft = ui32NumBytes; + g_psIOMBuffers[ui32Module].pfnCallback = pfnCallback; + g_psIOMBuffers[ui32Module].ui32Options = ui32Options; + + // + // Start the read transaction on the bus. + // + am_hal_iom_spi_cmd_run(AM_HAL_IOM_READ, ui32Module, ui32ChipSelect, + ui32NumBytes, ui32Options); + + am_hal_debug_assert_msg(ui32Status == 1,"IOM CMDCMP was not seen"); + + return ui32Status; +} + +static uint32_t +internal_am_hal_iom_spi_cmd_construct(uint32_t ui32Operation, + uint32_t ui32ChipSelect, + uint32_t ui32NumBytes, + uint32_t ui32Options) +{ + uint32_t ui32Command; + // + // Start building the command from the operation parameter. + // + ui32Command = ui32Operation; + + // + // Set the transfer length (the length field is split, so this requires + // some swizzling). + // + ui32Command |= ((ui32NumBytes & 0xF00) << 15); + ui32Command |= (ui32NumBytes & 0xFF); + + // + // Set the chip select number. + // + ui32Command |= ((ui32ChipSelect << 16) & 0x00070000); + + // + // Finally, OR in the rest of the options. This mask should make sure that + // erroneous option values won't interfere with the other transfer + // parameters. + // + ui32Command |= ui32Options & 0x5C00FF00; + return ui32Command; +} +//***************************************************************************** +// +//! @brief Runs a SPI "command" through the IO master. +//! +//! @param ui32Operation - SPI action to be performed. +//! +//! @param psDevice - Structure containing information about the slave device. +//! +//! @param ui32NumBytes - Number of bytes to move (transmit or receive) with +//! this command. +//! +//! @param ui32Options - Additional SPI options to apply to this command. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_spi_cmd_run(uint32_t ui32Operation, uint32_t ui32Module, + uint32_t ui32ChipSelect, uint32_t ui32NumBytes, + uint32_t ui32Options) +{ + uint32_t ui32Command; + + am_hal_debug_assert_msg(ui32NumBytes > 0, + "Trying to do a 0 byte transaction"); + ui32Command = internal_am_hal_iom_spi_cmd_construct(ui32Operation, + ui32ChipSelect, ui32NumBytes, ui32Options); + + + // + // Write the complete command word to the IOM command register. + // + AM_REGn(IOMSTR, ui32Module, CMD) = ui32Command; +} + +//***************************************************************************** +// +//! @brief Perform a simple write to the I2C interface (without queuing) +//! +//! @param ui32Module - Module number for the IOM. +//! @param ui32BusAddress - I2C address of the target device. +//! @param pui32Data - Pointer to the bytes that will be sent. +//! @param ui32NumBytes - Number of bytes to send. +//! @param ui32Options - Additional I2C transfer options. +//! +//! This function performs I2C writes to a selected I2C device. +//! +//! This function call is a blocking implementation. It will write as much +//! data to the FIFO as possible immediately, and then refill the FIFO as data +//! is transmiitted. +//! +//! @note The actual SPI and I2C interfaces operate in BYTES, not 32-bit words +//! This means that you will need to byte-pack the \e pui32Data array with the +//! data you intend to send over the interface. One easy way to do this is to +//! declare the array as a 32-bit integer array, but use an 8-bit pointer to +//! put your actual data into the array. If there are not enough bytes in your +//! desired message to completely fill the last 32-bit word, you may pad that +//! last word with bytes of any value. The IOM hardware will only read the +//! first \e ui32NumBytes in the \e pui32Data array. +//! +//! @return None. +// +//***************************************************************************** +uint32_t +am_hal_iom_i2c_write_nq(uint32_t ui32Module, uint32_t ui32BusAddress, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options) +{ + uint32_t ui32TransferSize; + uint32_t ui32SpaceInFifo; + uint32_t ui32IntConfig; + uint32_t ui32MaxFifoSize; + uint32_t ui32Status = 1; + + // + // Validate parameters + // + if ( ui32Module > AM_REG_IOMSTR_NUM_MODULES ) + { + return 0; + } + am_hal_debug_assert_msg(ui32NumBytes > 0, + "Trying to do a 0 byte transaction"); + + // + // Redirect to the bit-bang interface if the module number matches the + // software I2C module. + // + if ( ui32Module == AM_HAL_IOM_I2CBB_MODULE ) + { + if ( ui32Options & AM_HAL_IOM_RAW ) + { + am_hal_i2c_bit_bang_send(ui32BusAddress << 1, ui32NumBytes, + (uint8_t *)pui32Data, 0, false, + (ui32Options & AM_HAL_IOM_NO_STOP)); + } + else + { + am_hal_i2c_bit_bang_send(ui32BusAddress << 1, ui32NumBytes, + (uint8_t *)pui32Data, + ((ui32Options & 0xFF00) >> 8), + true, + (ui32Options & AM_HAL_IOM_NO_STOP)); + } + + // + // Return. + // + return 0; + } + + // + // Make sure the transfer isn't too long for the hardware to support. + // + am_hal_debug_assert_msg(ui32NumBytes < 256, "I2C transfer too big."); + + ui32MaxFifoSize = ((0 == AM_BFRn(IOMSTR, ui32Module, CFG, FULLDUP)) ? + AM_HAL_IOM_MAX_FIFO_SIZE : AM_HAL_IOM_MAX_FIFO_SIZE / 2); + + // + // Wait until any earlier transactions have completed. + // + am_hal_iom_poll_complete(ui32Module); + + // + // Disable interrupts so that we don't get any undesired interrupts. + // + ui32IntConfig = AM_REGn(IOMSTR, ui32Module, INTEN); + AM_REGn(IOMSTR, ui32Module, INTEN) = 0; + + // + // Clear CMDCMP status + // + AM_BFWn(IOMSTR, ui32Module, INTCLR, CMDCMP, 1); + + // + // Figure out how many bytes we can write to the FIFO immediately. + // + ui32TransferSize = (ui32NumBytes <= ui32MaxFifoSize ? ui32NumBytes : + ui32MaxFifoSize); + + am_hal_iom_fifo_write(ui32Module, pui32Data, ui32TransferSize); + + // + // Start the write on the bus. + // + am_hal_iom_i2c_cmd_run(AM_HAL_IOM_WRITE, ui32Module, ui32BusAddress, + ui32NumBytes, ui32Options); + + // + // Update the pointer and data counter. + // + ui32NumBytes -= ui32TransferSize; + pui32Data += ui32TransferSize >> 2; + + // + // Keep looping until we're out of bytes to send or command complete (error). + // + while ( ui32NumBytes && !AM_BFRn(IOMSTR, ui32Module, INTSTAT, CMDCMP) ) + { + // + // This will always return a multiple of four. + // + ui32SpaceInFifo = am_hal_iom_fifo_empty_slots(ui32Module); + + if ( ui32NumBytes <= ui32SpaceInFifo ) + { + // + // If the entire message will fit in the fifo, prepare to copy + // everything. + // + ui32TransferSize = ui32NumBytes; + } + else + { + // + // If only a portion of the message will fit in the fifo, prepare + // to copy the largest number of 4-byte blocks possible. + // + ui32TransferSize = ui32SpaceInFifo; + } + + // + // Write this chunk to the fifo. + // + am_hal_iom_fifo_write(ui32Module, pui32Data, ui32TransferSize); + + // + // Update the data pointer and bytes-left count. + // + ui32NumBytes -= ui32TransferSize; + pui32Data += ui32TransferSize >> 2; + } + + // + // Make sure CMDCMP was raised, + // + ui32Status = am_util_wait_status_change(ui32StatusTimeout[ui32Module], + AM_REG_IOMSTRn(ui32Module) + AM_REG_IOMSTR_INTSTAT_O, + AM_REG_IOMSTR_INTEN_CMDCMP_M, AM_REG_IOMSTR_INTEN_CMDCMP_M); + + // + // Re-enable IOM interrupts. Make sure CMDCMP is cleared + // + AM_REGn(IOMSTR, ui32Module, INTCLR) = (ui32IntConfig | AM_REG_IOMSTR_INTSTAT_CMDCMP_M); + AM_REGn(IOMSTR, ui32Module, INTEN) = ui32IntConfig; + + am_hal_debug_assert_msg(ui32Status == 1,"IOM CMDCMP was not seen"); + + // + // Return the status (0 = timeout; 1 = success) + // + return ui32Status; +} + +//***************************************************************************** +// +//! @brief Perform simple I2C read operations (without queuing). +//! +//! @param ui32Module - Module number for the IOM. +//! @param ui32BusAddress - I2C address of the target device. +//! @param pui32Data - Pointer to the array where received bytes should go. +//! @param ui32NumBytes - Number of bytes to read. +//! @param ui32Options - Additional I2C transfer options. +//! +//! This function performs an I2C read to a selected I2C device. +//! +//! This function call is a blocking implementation. It will read as much +//! data from the FIFO as possible immediately, and then re-read the FIFO as more +//! data is available. +//! +//! @note The actual SPI and I2C interfaces operate in BYTES, not 32-bit words. +//! This function will pack the individual bytes from the physical interface +//! into 32-bit words, which are then placed into the \e pui32Data array. Only +//! the first \e ui32NumBytes bytes in this array will contain valid data. +//! +//! @return None. +// +//***************************************************************************** +uint32_t +am_hal_iom_i2c_read_nq(uint32_t ui32Module, uint32_t ui32BusAddress, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options) +{ + uint32_t ui32BytesInFifo; + uint32_t ui32IntConfig; + uint32_t bCmdCmp = false; + uint32_t ui32Status = 1; + + // + // Validate parameters + // + if ( ui32Module > AM_REG_IOMSTR_NUM_MODULES ) + { + return 0; + } + am_hal_debug_assert_msg(ui32NumBytes > 0, + "Trying to do a 0 byte transaction"); + + // + // Redirect to the bit-bang interface if the module number matches the + // software I2C module. + // + if ( ui32Module == AM_HAL_IOM_I2CBB_MODULE ) + { + if ( ui32Options & AM_HAL_IOM_RAW ) + { + am_hal_i2c_bit_bang_receive((ui32BusAddress << 1) | 1, ui32NumBytes, + (uint8_t *)pui32Data, 0, false, + (ui32Options & AM_HAL_IOM_NO_STOP)); + } + else + { + am_hal_i2c_bit_bang_receive((ui32BusAddress << 1) | 1, ui32NumBytes, + (uint8_t *)pui32Data, + ((ui32Options & 0xFF00) >> 8), + true, + (ui32Options & AM_HAL_IOM_NO_STOP)); + } + + // + // Return. + // + return 0; + } + + // + // Make sure the transfer isn't too long for the hardware to support. + // + am_hal_debug_assert_msg(ui32NumBytes < 256, "I2C transfer too big."); + + // + // Wait until the bus is idle + // + am_hal_iom_poll_complete(ui32Module); + + // + // Disable interrupts so that we don't get any undesired interrupts. + // + ui32IntConfig = AM_REGn(IOMSTR, ui32Module, INTEN); + AM_REGn(IOMSTR, ui32Module, INTEN) = 0; + + // + // Clear CMDCMP status + // + AM_BFWn(IOMSTR, ui32Module, INTCLR, CMDCMP, 1); + + am_hal_iom_i2c_cmd_run(AM_HAL_IOM_READ, ui32Module, ui32BusAddress, + ui32NumBytes, ui32Options); + + // + // Start a loop to catch the Rx data. + // + while ( ui32NumBytes ) + { + ui32BytesInFifo = am_hal_iom_fifo_full_slots(ui32Module); + + if ( ui32BytesInFifo >= ui32NumBytes ) + { + // + // If the fifo contains our entire message, just copy the whole + // thing out. + // + am_hal_iom_fifo_read(ui32Module, pui32Data, ui32NumBytes); + ui32NumBytes = 0; + } + else if ( ui32BytesInFifo >= 4 ) + { + // + // If the fifo has at least one 32-bit word in it, copy whole + // words out. + // + am_hal_iom_fifo_read(ui32Module, pui32Data, ui32BytesInFifo & ~0x3); + + ui32NumBytes -= ui32BytesInFifo & ~0x3; + pui32Data += ui32BytesInFifo >> 2; + } + + if ( bCmdCmp == true ) + { + // No more data expected - exit out of loop + break; + } + + bCmdCmp = AM_BFRn(IOMSTR, ui32Module, INTSTAT, CMDCMP); + } + + // + // Make sure CMDCMP was raised, + // + ui32Status = am_util_wait_status_change(ui32StatusTimeout[ui32Module], + AM_REG_IOMSTRn(ui32Module) + AM_REG_IOMSTR_INTSTAT_O, + AM_REG_IOMSTR_INTEN_CMDCMP_M, AM_REG_IOMSTR_INTEN_CMDCMP_M); + + // + // Re-enable IOM interrupts. Make sure CMDCMP is cleared + // + AM_REGn(IOMSTR, ui32Module, INTCLR) = (ui32IntConfig | AM_REG_IOMSTR_INTSTAT_CMDCMP_M); + AM_REGn(IOMSTR, ui32Module, INTEN) = ui32IntConfig; + + am_hal_debug_assert_msg(ui32Status == 1,"IOM CMDCMP was not seen"); + + // + // Return the status (0 = timeout; 1 = success) + // + return ui32Status; +} + +//***************************************************************************** +// +//! @brief Perform a simple write to the I2C interface. +//! +//! @param ui32Module - Module number for the IOM +//! @param ui32BusAddress - I2C bus address for this transaction. +//! @param pui32Data - Pointer to the bytes that will be sent. +//! @param ui32NumBytes - Number of bytes to send. +//! @param ui32Options - Additional options +//! +//! Performs a write to the I2C interface using the provided parameters. +//! +//! See the "Command Options" section for parameters that may be ORed together +//! and used in the \b ui32Options parameter. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_i2c_write(uint32_t ui32Module, uint32_t ui32BusAddress, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options) +{ + // + // Validate parameters + // + if ( ui32Module > AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + am_hal_debug_assert_msg(ui32NumBytes > 0, + "Trying to do a 0 byte transaction"); + + // + // Redirect to the bit-bang interface if the module number matches the + // software I2C module. + // + if ( ui32Module == AM_HAL_IOM_I2CBB_MODULE ) + { + if ( ui32Options & AM_HAL_IOM_RAW ) + { + am_hal_i2c_bit_bang_send(ui32BusAddress << 1, ui32NumBytes, + (uint8_t *)pui32Data, 0, false, + (ui32Options & AM_HAL_IOM_NO_STOP)); + } + else + { + am_hal_i2c_bit_bang_send(ui32BusAddress << 1, ui32NumBytes, + (uint8_t *)pui32Data, + ((ui32Options & 0xFF00) >> 8), + true, + (ui32Options & AM_HAL_IOM_NO_STOP)); + } + + // + // Return. + // + return; + } + + // + // Make sure the transfer isn't too long for the hardware to support. + // + am_hal_debug_assert_msg(ui32NumBytes < 256, "I2C transfer too big."); + + // + // Check to see if queues have been enabled. If they are, we'll actually + // switch to the queued interface. + // + if ( g_psIOMQueue[ui32Module].pui8Data != NULL ) + { + // + // If the queue is on, go ahead and add this transaction to the queue. + // + am_hal_iom_queue_i2c_write(ui32Module, ui32BusAddress, pui32Data, + ui32NumBytes, ui32Options, 0); + + // + // Wait until the transaction actually clears. + // + am_hal_iom_queue_flush(ui32Module); + + // + // At this point, we've completed the transaction, and we can return. + // + return; + } + else + { + // + // Otherwise, we'll just do a polled transaction. + // + am_hal_iom_i2c_write_nq(ui32Module, ui32BusAddress, pui32Data, + ui32NumBytes, ui32Options); + } +} + +//***************************************************************************** +// +//! @brief Perform simple I2C read operations. +//! +//! @param ui32Module - Module number for the IOM +//! @param ui32BusAddress - I2C bus address for this transaction. +//! @param pui32Data - Pointer to the array where received bytes should go. +//! @param ui32NumBytes - Number of bytes to read. +//! @param ui32Options - Additional I2C transfer options. +//! +//! This function performs simple I2C read operations. The caller is +//! responsible for ensuring that the receive buffer is large enough to hold +//! the requested amount of data. If \e bPolled is true, this function will +//! block until all of the requested data has been received and placed in the +//! user-supplied buffer. Otherwise, the function will execute the I2C read +//! command and return immediately. The user-supplied buffer will be filled +//! with the received I2C data as it comes in over the physical interface, and +//! the "command complete" interrupt bit will become active once the entire +//! message is available. +//! +//! See the "Command Options" section for parameters that may be ORed together +//! and used in the \b ui32Options parameter. +//! +//! @note The actual SPI and I2C interfaces operate in BYTES, not 32-bit words. +//! This function will pack the individual bytes from the physical interface +//! into 32-bit words, which are then placed into the \e pui32Data array. Only +//! the first \e ui32NumBytes bytes in this array will contain valid data. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_i2c_read(uint32_t ui32Module, uint32_t ui32BusAddress, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options) +{ + // + // Validate parameters + // + if ( ui32Module > AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + am_hal_debug_assert_msg(ui32NumBytes > 0, + "Trying to do a 0 byte transaction"); + + // + // Redirect to the bit-bang interface if the module number matches the + // software I2C module. + // + if ( ui32Module == AM_HAL_IOM_I2CBB_MODULE ) + { + if ( ui32Options & AM_HAL_IOM_RAW ) + { + am_hal_i2c_bit_bang_receive((ui32BusAddress << 1) | 1, ui32NumBytes, + (uint8_t *)pui32Data, 0, false, + (ui32Options & AM_HAL_IOM_NO_STOP)); + } + else + { + am_hal_i2c_bit_bang_receive((ui32BusAddress << 1) | 1, ui32NumBytes, + (uint8_t *)pui32Data, + ((ui32Options & 0xFF00) >> 8), + true, + (ui32Options & AM_HAL_IOM_NO_STOP)); + } + + // + // Return. + // + return; + } + + // + // Make sure the transfer isn't too long for the hardware to support. + // + am_hal_debug_assert_msg(ui32NumBytes < 256, "I2C transfer too big."); + + // + // Check to see if queues have been enabled. If they are, we'll actually + // switch to the queued interface. + // + if ( g_psIOMQueue[ui32Module].pui8Data != NULL ) + { + // + // If the queue is on, go ahead and add this transaction to the queue. + // + am_hal_iom_queue_i2c_read(ui32Module, ui32BusAddress, pui32Data, + ui32NumBytes, ui32Options, 0); + + // + // Wait until the transaction actually clears. + // + am_hal_iom_queue_flush(ui32Module); + + // + // At this point, we've completed the transaction, and we can return. + // + return; + } + else + { + // + // Otherwise, just perform a polled transaction. + // + am_hal_iom_i2c_read_nq(ui32Module, ui32BusAddress, pui32Data, + ui32NumBytes, ui32Options); + } +} + +//***************************************************************************** +// +//! @brief Perform a non-blocking write to the I2C interface. +//! +//! @param ui32Module - Module number for the IOM. +//! @param ui32BusAddress - I2C address of the target device. +//! @param pui32Data - Pointer to the bytes that will be sent. +//! @param ui32NumBytes - Number of bytes to send. +//! @param ui32Options - Additional I2C transfer options. +//! @param pfnCallback - Function to call when the transaction completes. +//! +//! This function performs I2C writes to a selected I2C device. +//! +//! This function call is a non-blocking implementation. It will write as much +//! data to the FIFO as possible immediately, store a pointer to the remaining +//! data, start the transfer on the bus, and then immediately return. The +//! caller will need to make sure that \e am_hal_iom_int_service() is called +//! for IOM FIFO interrupt events and "command complete" interrupt events. The +//! \e am_hal_iom_int_service() function will refill the FIFO as necessary and +//! call the \e pfnCallback function when the transaction is finished. +//! +//! @note The actual SPI and I2C interfaces operate in BYTES, not 32-bit words. +//! This means that you will need to byte-pack the \e pui32Data array with the +//! data you intend to send over the interface. One easy way to do this is to +//! declare the array as a 32-bit integer array, but use an 8-bit pointer to +//! put your actual data into the array. If there are not enough bytes in your +//! desired message to completely fill the last 32-bit word, you may pad that +//! last word with bytes of any value. The IOM hardware will only read the +//! first \e ui32NumBytes in the \e pui32Data array. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_i2c_write_nb(uint32_t ui32Module, uint32_t ui32BusAddress, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options, + am_hal_iom_callback_t pfnCallback) +{ + uint32_t ui32TransferSize; + uint32_t ui32MaxFifoSize; + + // + // Validate parameters + // + if ( ui32Module > AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + am_hal_debug_assert_msg(ui32NumBytes > 0, + "Trying to do a 0 byte transaction"); + + // + // Redirect to the bit-bang interface if the module number matches the + // software I2C module. + // + if ( ui32Module == AM_HAL_IOM_I2CBB_MODULE ) + { + if ( ui32Options & AM_HAL_IOM_RAW ) + { + am_hal_i2c_bit_bang_send(ui32BusAddress << 1, ui32NumBytes, + (uint8_t *)pui32Data, 0, false, + (ui32Options & AM_HAL_IOM_NO_STOP)); + } + else + { + am_hal_i2c_bit_bang_send(ui32BusAddress << 1, ui32NumBytes, + (uint8_t *)pui32Data, + ((ui32Options & 0xFF00) >> 8), + true, + (ui32Options & AM_HAL_IOM_NO_STOP)); + } + + // + // The I2C bit-bang interface is actually a blocking transfer, and it + // doesn't trigger the interrupt handler, so we have to call the + // callback function manually. + // + if ( pfnCallback ) + { + pfnCallback(); + } + // + // Return. + // + return; + } + + // + // Make sure the transfer isn't too long for the hardware to support. + // + am_hal_debug_assert_msg(ui32NumBytes < 256, "I2C transfer too big."); + + ui32MaxFifoSize = ((0 == AM_BFRn(IOMSTR, ui32Module, CFG, FULLDUP)) ? + AM_HAL_IOM_MAX_FIFO_SIZE : AM_HAL_IOM_MAX_FIFO_SIZE / 2); + + // + // Figure out how many bytes we can write to the FIFO immediately. + // + ui32TransferSize = (ui32NumBytes <= ui32MaxFifoSize ? ui32NumBytes : + ui32MaxFifoSize); + + // + // Wait until any earlier transactions have completed, and then write our + // first word to the fifo. + // + am_hal_iom_poll_complete(ui32Module); + + // Need to mark IOM busy to avoid another transaction to be scheduled. + // This is to take care of a race condition in Queue mode, where the IDLE + // set is not a guarantee that the CMDCMP has been received + g_bIomBusy[ui32Module] = true; + + // + // Clear CMDCMP status + // + AM_BFWn(IOMSTR, ui32Module, INTCLR, CMDCMP, 1); + + if ( am_hal_iom_fifo_write(ui32Module, pui32Data, ui32TransferSize) > 0 ) + { + // + // Prepare the global IOM buffer structure. + // + g_psIOMBuffers[ui32Module].ui32State = BUFFER_SENDING; + g_psIOMBuffers[ui32Module].pui32Data = pui32Data; + g_psIOMBuffers[ui32Module].ui32BytesLeft = ui32NumBytes; + g_psIOMBuffers[ui32Module].pfnCallback = pfnCallback; + + // + // Update the pointer and the byte counter based on the portion of the + // transfer we just sent to the fifo. + // + g_psIOMBuffers[ui32Module].ui32BytesLeft -= ui32TransferSize; + g_psIOMBuffers[ui32Module].pui32Data += (ui32TransferSize / 4); + + // + // Start the write on the bus. + // + am_hal_iom_i2c_cmd_run(AM_HAL_IOM_WRITE, ui32Module, ui32BusAddress, + ui32NumBytes, ui32Options); + } +} + +//***************************************************************************** +// +//! @brief Perform a non-blocking I2C read. +//! +//! @param ui32Module - Module number for the IOM. +//! @param ui32ChipSelect - I2C address of the target device. +//! @param pui32Data - Pointer to the array where received bytes should go. +//! @param ui32NumBytes - Number of bytes to read. +//! @param ui32Options - Additional I2C transfer options. +//! @param pfnCallback - Function to call when the transaction completes. +//! +//! This function performs an I2C read to a selected I2C device. +//! +//! This function call is a non-blocking implementation. It will start the I2C +//! transaction on the bus and store a pointer for the destination for the read +//! data, but it will not wait for the I2C transaction to finish. The caller +//! will need to make sure that \e am_hal_iom_int_service() is called for IOM +//! FIFO interrupt events and "command complete" interrupt events. The \e +//! am_hal_iom_int_service() function will empty the FIFO as necessary, +//! transfer the data to the \e pui32Data buffer, and call the \e pfnCallback +//! function when the transaction is finished. +//! +//! @note The actual SPI and I2C interfaces operate in BYTES, not 32-bit words. +//! This function will pack the individual bytes from the physical interface +//! into 32-bit words, which are then placed into the \e pui32Data array. Only +//! the first \e ui32NumBytes bytes in this array will contain valid data. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_i2c_read_nb(uint32_t ui32Module, uint32_t ui32BusAddress, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options, + am_hal_iom_callback_t pfnCallback) +{ + // + // Validate parameters + // + if ( ui32Module > AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + am_hal_debug_assert_msg(ui32NumBytes > 0, + "Trying to do a 0 byte transaction"); + + // + // Redirect to the bit-bang interface if the module number matches the + // software I2C module. + // + if ( ui32Module == AM_HAL_IOM_I2CBB_MODULE ) + { + if ( ui32Options & AM_HAL_IOM_RAW ) + { + am_hal_i2c_bit_bang_receive((ui32BusAddress << 1) | 1, ui32NumBytes, + (uint8_t *)pui32Data, 0, false, + (ui32Options & AM_HAL_IOM_NO_STOP)); + } + else + { + am_hal_i2c_bit_bang_receive((ui32BusAddress << 1) | 1, ui32NumBytes, + (uint8_t *)pui32Data, + ((ui32Options & 0xFF00) >> 8), + true, + (ui32Options & AM_HAL_IOM_NO_STOP)); + } + + // + // The I2C bit-bang interface is actually a blocking transfer, and it + // doesn't trigger the interrupt handler, so we have to call the + // callback function manually. + // + if ( pfnCallback ) + { + pfnCallback(); + } + + // + // Return. + // + return; + } + + // + // Make sure the transfer isn't too long for the hardware to support. + // + am_hal_debug_assert_msg(ui32NumBytes < 256, "I2C transfer too big."); + + // + // Wait until the bus is idle + // + am_hal_iom_poll_complete(ui32Module); + + // + // Need to mark IOM busy to avoid another transaction to be scheduled. + // This is to take care of a race condition in Queue mode, where the IDLE + // set is not a guarantee that the CMDCMP has been received + // + g_bIomBusy[ui32Module] = true; + + // + // Clear CMDCMP status + // + AM_BFWn(IOMSTR, ui32Module, INTCLR, CMDCMP, 1); + + // + // Prepare the global IOM buffer structure. + // + g_psIOMBuffers[ui32Module].ui32State = BUFFER_RECEIVING; + g_psIOMBuffers[ui32Module].pui32Data = pui32Data; + g_psIOMBuffers[ui32Module].ui32BytesLeft = ui32NumBytes; + g_psIOMBuffers[ui32Module].pfnCallback = pfnCallback; + + // + // Start the read transaction on the bus. + // + am_hal_iom_i2c_cmd_run(AM_HAL_IOM_READ, ui32Module, ui32BusAddress, + ui32NumBytes, ui32Options); +} + +//***************************************************************************** +// +//! @brief Runs a I2C "command" through the IO master. +//! +//! @param ui32Operation - I2C action to be performed. This should either be +//! AM_HAL_IOM_WRITE or AM_HAL_IOM_READ. +//! @param psDevice - Structure containing information about the slave device. +//! @param ui32NumBytes - Number of bytes to move (transmit or receive) with +//! this command. +//! @param ui32Options - Additional I2C options to apply to this command. +//! +//! This function may be used along with am_hal_iom_fifo_write and +//! am_hal_iom_fifo_read to perform more complex I2C reads and writes. This +//! function +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_i2c_cmd_run(uint32_t ui32Operation, uint32_t ui32Module, + uint32_t ui32BusAddress, uint32_t ui32NumBytes, + uint32_t ui32Options) +{ + uint32_t ui32Command; + + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + am_hal_debug_assert_msg(ui32NumBytes > 0, + "Trying to do a 0 byte transaction"); + + // + // Start building the command from the operation parameter. + // + ui32Command = ui32Operation; + + // + // Set the transfer length. + // + ui32Command |= (ui32NumBytes & 0xFF); + + // + // Set the chip select number. + // + ui32Command |= ((ui32BusAddress << 16) & 0x03FF0000); + + // + // Finally, OR in the rest of the options. This mask should make sure that + // erroneous option values won't interfere with the other transfer + // parameters. + // + ui32Command |= (ui32Options & 0x5C00FF00); + + // + // Write the complete command word to the IOM command register. + // + AM_REGn(IOMSTR, ui32Module, CMD) = ui32Command; +} + +//***************************************************************************** +// +//! @brief Sets the repeat count for the next IOM command. +//! +//! @param ui32Module is the IOM module number. +//! @param ui32CmdCount is the number of times the next command should be +//! executed. +//! +//! @note This function is not compatible with the am_hal_iom_spi_read/write() +//! or am_hal_iom_i2c_read/write() functions. Instead, you will need to use the +//! am_hal_iom_fifo_read/write() functions and the am_hal_iom_spi/i2c_cmd_run() +//! functions. +//! +//! Example usage: +//! @code +//! +//! // +//! // Create a buffer and add 3 bytes of data to it. +//! // +//! am_hal_iom_buffer(3) psBuffer; +//! psBuffer.bytes[0] = 's'; +//! psBuffer.bytes[1] = 'p'; +//! psBuffer.bytes[2] = 'i'; +//! +//! // +//! // Send three different bytes to the same SPI register on a remote device. +//! // +//! am_hal_iom_fifo_write(ui32Module, psBuffer.words, 3); +//! +//! am_hal_command_repeat_set(ui32Module, 3); +//! +//! am_hal_iom_spi_cmd_run(AM_HAL_IOM_WRITE, psDevice, 1, +//! AM_HAL_IOM_OFFSET(0x5)); +//! +//! // +//! // The sequence "0x5, 's', 0x5, 'p', 0x5, 'i'" should be written to the SPI +//! // bus. +//! // +//! +//! @endcode +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_command_repeat_set(uint32_t ui32Module, uint32_t ui32CmdCount) +{ + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + + AM_REGn(IOMSTR, ui32Module, CMDRPT) = ui32CmdCount; +} + +//***************************************************************************** +// +//! @brief Writes data to the IOM FIFO. +//! +//! @param ui32Module - Selects the IOM module to use (zero or one). +//! @param pui32Data - Pointer to an array of the data to be written. +//! @param ui32NumBytes - Number of BYTES to copy into the FIFO. +//! +//! This function copies data from the array \e pui32Data into the IOM FIFO. +//! This prepares the data to eventually be sent as SPI or I2C data by an IOM +//! "command". +//! +//! @note The actual SPI and I2C interfaces operate in BYTES, not 32-bit words. +//! This means that you will need to byte-pack the \e pui32Data array with the +//! data you intend to send over the interface. One easy way to do this is to +//! declare the array as a 32-bit integer array, but use an 8-bit pointer to +//! put your actual data into the array. If there are not enough bytes in your +//! desired message to completely fill the last 32-bit word, you may pad that +//! last word with bytes of any value. The IOM hardware will only read the +//! first \e ui32NumBytes in the \e pui8Data array. +//! +//! @note This function may be used to write partial or complete SPI or I2C +//! messages into the IOM FIFO. When writing partial messages to the FIFO, make +//! sure that the number of bytes written is a multiple of four. Only the last +//! 'part' of a message may consist of a number of bytes that is not a multiple +//! of four. If this rule is not followed, the IOM will not be able to send +//! these bytes correctly. +//! +//! @return Number of bytes actually written to the FIFO. +// +//***************************************************************************** +uint32_t +am_hal_iom_fifo_write(uint32_t ui32Module, uint32_t *pui32Data, + uint32_t ui32NumBytes) +{ + uint32_t ui32Index; + + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return 0; + } + + // + // Make sure we check the number of bytes we're writing to the FIFO. + // + am_hal_debug_assert_msg((am_hal_iom_fifo_empty_slots(ui32Module) >= ui32NumBytes), + "The fifo couldn't fit the requested number of bytes"); + + // + // Loop over the words in the array until we have the correct number of + // bytes. + // + for ( ui32Index = 0; (4 * ui32Index) < ui32NumBytes; ui32Index++ ) + { + // + // Write the word to the FIFO. + // + AM_REGn(IOMSTR, ui32Module, FIFO) = pui32Data[ui32Index]; + } + + return ui32NumBytes; +} + +//***************************************************************************** +// +//! @brief Reads data from the IOM FIFO. +//! +//! @param ui32Module - Selects the IOM module to use (zero or one). +//! @param pui32Data - Pointer to an array where the FIFO data will be copied. +//! @param ui32NumBytes - Number of bytes to copy into array. +//! +//! This function copies data from the IOM FIFO into the array \e pui32Data. +//! This is how input data from SPI or I2C transactions may be retrieved. +//! +//! @note The actual SPI and I2C interfaces operate in BYTES, not 32-bit words. +//! This function will pack the individual bytes from the physical interface +//! into 32-bit words, which are then placed into the \e pui32Data array. Only +//! the first \e ui32NumBytes bytes in this array will contain valid data. +//! +//! @return Number of bytes read from the fifo. +// +//***************************************************************************** +uint32_t +am_hal_iom_fifo_read(uint32_t ui32Module, uint32_t *pui32Data, + uint32_t ui32NumBytes) +{ + am_hal_iom_buffer(4) sTempBuffer; + uint32_t i, j, ui32NumWords, ui32Leftovers; + uint8_t *pui8Data; + + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return 0; + } + + // + // Make sure we check the number of bytes we're reading from the FIFO. + // + am_hal_debug_assert_msg((am_hal_iom_fifo_full_slots(ui32Module) >= ui32NumBytes), + "The fifo doesn't contain the requested number of bytes."); + + // + // Figure out how many whole words we're reading from the fifo, and how + // many bytes will be left over when we're done. + // + ui32NumWords = ui32NumBytes / 4; + ui32Leftovers = ui32NumBytes - (ui32NumWords * 4); + + // + // Copy out as many full words as we can. + // + for ( i = 0; i < ui32NumWords; i++ ) + { + // + // Copy data out of the FIFO, one word at a time. + // + pui32Data[i] = AM_REGn(IOMSTR, ui32Module, FIFO); + } + + // + // If there were leftovers, we'll copy them carefully. Pull the last word + // from the fifo (there should only be one) into a temporary buffer. Also, + // create an 8-bit pointer to help us copy the remaining bytes one at a + // time. + // + // Note: If the data buffer we were given was truly a word pointer like the + // definition requests, we wouldn't need to do this. It's possible to call + // this function with a re-cast or packed pointer instead though. If that + // happens, we want to be careful not to overwrite any data that might be + // sitting just past the end of the destination array. + // + if ( ui32Leftovers ) + { + sTempBuffer.words[0] = AM_REGn(IOMSTR, ui32Module, FIFO); + pui8Data = (uint8_t *) (&pui32Data[i]); + + // + // If we had leftover bytes, copy them out one byte at a time. + // + for ( j = 0; j < ui32Leftovers; j++ ) + { + pui8Data[j] = sTempBuffer.bytes[j]; + } + } + + return ui32NumBytes; +} + +//***************************************************************************** +// +//! @brief Check amount of empty space in the IOM fifo. +//! +//! @param ui32Module - Module number of the IOM whose fifo should be checked. +//! +//! Returns the number of bytes that could be written to the IOM fifo without +//! causing an overflow. +//! +//! @return Amount of space available in the fifo (in bytes). +// +//***************************************************************************** +uint8_t +am_hal_iom_fifo_empty_slots(uint32_t ui32Module) +{ + uint32_t ui32MaxFifoSize; + + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return 0; + } + + ui32MaxFifoSize = ((0 == AM_BFRn(IOMSTR, ui32Module, CFG, FULLDUP)) ? AM_HAL_IOM_MAX_FIFO_SIZE : AM_HAL_IOM_MAX_FIFO_SIZE / 2); + + // + // Calculate the FIFO Remaining from the FIFO size. This will be different + // depending on whether the IOM is configured for half-duplex or + // full-duplex. + // + return (ui32MaxFifoSize - AM_BFRn(IOMSTR, ui32Module, FIFOPTR, FIFOSIZ)) & (~0x3); +} + +//***************************************************************************** +// +//! @brief Check to see how much data is in the IOM fifo. +//! +//! @param ui32Module - Module number of the IOM whose fifo should be checked. +//! +//! Returns the number of bytes of data that are currently in the IOM fifo. +//! +//! @return Number of bytes in the fifo. +// +//***************************************************************************** +uint8_t +am_hal_iom_fifo_full_slots(uint32_t ui32Module) +{ + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return 0; + } + + return AM_BFRn(IOMSTR, ui32Module, FIFOPTR, FIFOSIZ); +} + +//***************************************************************************** +// +//! @brief Wait for the current IOM command to complete. +//! +//! @param ui32Module - The module number of the IOM to use. +//! +//! This function polls until the IOM bus becomes idle. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_poll_complete(uint32_t ui32Module) +{ + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + + // + // Poll on the IDLE bit in the status register. + // + while ( g_bIomBusy[ui32Module] ); +} + +//***************************************************************************** +// +//! @brief Returns the contents of the IOM status register. +//! +//! @param ui32Module IOM instance to check the status of. +//! +//! This function is just a wrapper around the IOM status register. +//! +//! @return 32-bit contents of IOM status register. +// +//***************************************************************************** +uint32_t +am_hal_iom_status_get(uint32_t ui32Module) +{ + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return 0; + } + + return AM_REGn(IOMSTR, ui32Module, STATUS); +} + +//***************************************************************************** +// +//! @brief Returns current error state of the IOM. +//! +//! @param ui32Module IOM instance to check the status of. +//! +//! This function returns status indicating whether the IOM has incurred any +//! errors or not. +//! +//! @return 0 if all is well. +//! Otherwise error status as a bitmask of: +//! AM_HAL_IOM_ERR_INVALID_MODULE +//! AM_HAL_IOM_INT_ARB Another master initiated an operation +//! simultaenously and the IOM lost. Or +//! the IOM started an operation but found +//! SDA already low. +//! AM_HAL_IOM_INT_START A START from another master detected. +//! SW must wait for STOP before continuing. +//! AM_HAL_IOM_INT_ICMD Attempt to issue a CMD while another +//! CMD was already in progress, or issue a +//! non-zero-len write CMD with empty FIFO. +//! AM_HAL_IOM_INT_IACC Attempt to read the FIFO on a write. Or +//! an attempt to write the FIFO on a read. +//! AM_HAL_IOM_INT_NAK Expected ACK from slave not received. +//! AM_HAL_IOM_INT_FOVFL Attempt to write the FIFO while full +//! (FIFOSIZ > 124). +//! AM_HAL_IOM_INT_FUNDFL Attempt to read FIFO when empty (that is +//! FIFOSIZ < 4). +//! Note - see the datasheet text for full explanations of the INT errs. +// +//***************************************************************************** +uint32_t +am_hal_iom_error_status_get(uint32_t ui32Module) +{ + uint32_t ui32intstat = 0; + + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + // + // AM_HAL_IOM_ERR_INVALID_MODULE is defined as an unused interrupt bit. + // + return AM_HAL_IOM_ERR_INVALID_MODULE; + } + + if ( AM_REGn(IOMSTR, ui32Module, STATUS) & AM_REG_IOMSTR_STATUS_ERR_ERROR ) + { + // + // The IOM is currently indicating an error condition. + // Let's figure out what is going on. + // + ui32intstat = AM_REGn(IOMSTR, ui32Module, INTSTAT); + + // + // Filter out non-error bits. + // + ui32intstat &= AM_REG_IOMSTR_INTSTAT_ARB_M | + AM_REG_IOMSTR_INTSTAT_START_M | + AM_REG_IOMSTR_INTSTAT_ICMD_M | + AM_REG_IOMSTR_INTSTAT_IACC_M | + AM_REG_IOMSTR_INTSTAT_NAK_M | + AM_REG_IOMSTR_INTSTAT_FOVFL_M | + AM_REG_IOMSTR_INTSTAT_FUNDFL_M; + } + + return ui32intstat; +} + +//***************************************************************************** +// +//! @brief Service interrupts from the IOM. +//! +//! @param ui32Status is the IOM interrupt status as returned from +//! am_hal_iom_int_status_get() +//! +//! This function performs the necessary operations to facilitate non-blocking +//! IOM writes and reads. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_iom_int_service(uint32_t ui32Module, uint32_t ui32Status) +{ + am_hal_iom_nb_buffer *psBuffer; + uint32_t ui32NumBytes; + uint32_t ui32SpaceInFifo; + uint32_t thresh; + + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + // + // Find the buffer information for the chosen IOM module. + // + psBuffer = &g_psIOMBuffers[ui32Module]; + + // + // Figure out what type of interrupt this was. + // + if ( ui32Status & AM_HAL_IOM_INT_CMDCMP ) + { + // + // Need to mark IOM Free + // + g_bIomBusy[ui32Module] = false; + + // + // If we're not in the middle of a non-blocking call right now, there's + // nothing for this routine to do. + // + if ( psBuffer->ui32State == BUFFER_IDLE ) + { + return; + } + + // + // If a command just completed, we need to transfer all available data. + // + if ( psBuffer->ui32State == BUFFER_RECEIVING ) + { + // + // If we were receiving, we need to copy any remaining data out of + // the IOM FIFO before calling the callback. + // + ui32NumBytes = am_hal_iom_fifo_full_slots(ui32Module); + am_hal_iom_fifo_read(ui32Module, psBuffer->pui32Data, ui32NumBytes); + } + + // + // A command complete event also means that we've already transferred + // all of the data we need, so we can mark the data buffer as IDLE. + // + psBuffer->ui32State = BUFFER_IDLE; + + // + // If we have a callback, call it now. + // + if ( psBuffer->pfnCallback ) + { + psBuffer->pfnCallback(); + } + } + else if ( ui32Status & AM_HAL_IOM_INT_THR ) + { + // + // If we're not in the middle of a non-blocking call right now, there's + // nothing for this routine to do. + // + if ( psBuffer->ui32State == BUFFER_IDLE ) + { + return; + } + // + // If we received a threshold event in the middle of a command, we need + // to transfer data. + // + if ( psBuffer->ui32State == BUFFER_SENDING ) + { + thresh = AM_BFRn(IOMSTR, ui32Module, FIFOTHR, FIFOWTHR); + do + { + ui32SpaceInFifo = am_hal_iom_fifo_empty_slots(ui32Module); + + // + // Figure out how much data we can send. + // + if ( psBuffer->ui32BytesLeft <= ui32SpaceInFifo ) + { + // + // If the whole transfer will fit in the fifo, send it all. + // + ui32NumBytes = psBuffer->ui32BytesLeft; + } + else + { + // + // If the transfer won't fit in the fifo completely, send as + // much as we can (rounded down to a multiple of four bytes). + // + ui32NumBytes = ui32SpaceInFifo; + } + + // + // Perform the transfer. + // + am_hal_iom_fifo_write(ui32Module, psBuffer->pui32Data, ui32NumBytes); + + // Clear any spurious THR interrupt that might have got raised + // while we were adding data to FIFO + AM_BFWn(IOMSTR, ui32Module, INTCLR, THR, 1); + // + // Update the pointer and the byte counter. + // + psBuffer->ui32BytesLeft -= ui32NumBytes; + psBuffer->pui32Data += (ui32NumBytes / 4); + + if ( 0 == psBuffer->ui32BytesLeft ) + { + // + // Done with this transaction + // + break; + } + } while ( am_hal_iom_fifo_full_slots(ui32Module) <= thresh ); + } + else + { + thresh = AM_BFRn(IOMSTR, ui32Module, FIFOTHR, FIFORTHR); + while ( (ui32NumBytes = am_hal_iom_fifo_full_slots(ui32Module)) >= thresh ) + { + // + // If we get here, we're in the middle of a read. Transfer as much + // data as possible out of the FIFO and into our buffer. + // + if ( ui32NumBytes == psBuffer->ui32BytesLeft ) + { + // + // If the fifo contains our entire message, just copy the whole + // thing out. + // + am_hal_iom_fifo_read(ui32Module, psBuffer->pui32Data, + psBuffer->ui32BytesLeft); + + break; + } + else if ( ui32NumBytes >= 4 ) + { + // + // If the fifo has at least one 32-bit word in it, copy out the + // biggest block we can. + // + ui32NumBytes = (ui32NumBytes & (~0x3)); + + am_hal_iom_fifo_read(ui32Module, psBuffer->pui32Data, ui32NumBytes); + + // + // Update the pointer and the byte counter. + // + psBuffer->ui32BytesLeft -= ui32NumBytes; + psBuffer->pui32Data += (ui32NumBytes / 4); + + // Clear any spurious THR interrupt that might have got raised + // while we were reading the data from FIFO + AM_BFWn(IOMSTR, ui32Module, INTCLR, THR, 1); + } + } + } + } +} + +//***************************************************************************** +// +//! @brief Initialize the IOM queue system. +//! +//! @param ui32Module - IOM module to be initialized for queue transfers. +//! @param psQueueMemory - Memory to be used for queueing IOM transfers. +//! @param ui32QueueMemSize - Size of the queue memory. +//! +//! This function prepares the selected IOM interface for use with the IOM +//! queue system. The IOM queue system allows the caller to start multiple IOM +//! transfers in a non-blocking way. In order to do this, the HAL requires some +//! amount of memory dedicated to keeping track of IOM transactions before they +//! can be sent to the hardware registers. This function tells the HAL what +//! memory it should use for this purpose. For more information on the IOM +//! queue interface, please see the documentation for +//! am_hal_iom_queue_spi_write(). +//! +//! @note This function only needs to be called once (per module), but it must +//! be called before any other am_hal_iom_queue function. +//! +//! @note Each IOM module will need its own working space. If you intend to use +//! the queueing mechanism with more than one IOM module, you will need to +//! provide separate queue memory for each module. +//! +//! Example usage: +//! +//! @code +//! +//! // +//! // Declare an array to be used for IOM queue transactions. This array will +//! // be big enough to handle 32 IOM transactions. +//! // +//! am_hal_iom_queue_entry_t g_psQueueMemory[32]; +//! +//! // +//! // Attach the IOM0 queue system to the memory we just allocated. +//! // +//! am_hal_iom_queue_init(0, g_psQueueMemory, sizeof(g_psQueueMemory)); +//! +//! @endcode +// +//***************************************************************************** +void +am_hal_iom_queue_init(uint32_t ui32Module, am_hal_iom_queue_entry_t *psQueueMemory, + uint32_t ui32QueueMemSize) +{ + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + + am_hal_queue_init(&g_psIOMQueue[ui32Module], psQueueMemory, + sizeof(am_hal_iom_queue_entry_t), ui32QueueMemSize); +} + +//***************************************************************************** +// +//! @brief Check to see how many transactions are in the queue. +//! +//! @param ui32Module Module number for the queue to check +//! +//! This function will check to see how many transactions are in the IOM queue +//! for the selected IOM module. +//! +//! @return Number of transactions in the queue. +// +//***************************************************************************** +uint32_t +am_hal_iom_queue_length_get(uint32_t ui32Module) +{ + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return 0; + } + + return am_hal_queue_data_left(&g_psIOMQueue[ui32Module]); +} + +//***************************************************************************** +// +//! @brief Executes the next operation in the IOM queue. +//! +//! @param ui32ModuleNum - Module number for the IOM to use. +//! +//! This function checks the IOM queue to see if there are any remaining +//! transactions. If so, it will start the next available transaction in a +//! non-blocking way. +//! +//! @note This function is called automatically by am_hal_iom_queue_service(). +//! You should not call this function standalone in a normal application. +// +//***************************************************************************** +void +am_hal_iom_queue_start_next_msg(uint32_t ui32Module) +{ + am_hal_iom_queue_entry_t sIOMTransaction = {0}; + + uint32_t ui32ChipSelect; + uint32_t *pui32Data; + uint32_t ui32NumBytes; + uint32_t ui32Options; + am_hal_iom_callback_t pfnCallback; + + uint32_t ui32Critical; + + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + + // + // Start a critical section. + // + ui32Critical = am_hal_interrupt_master_disable(); + + // + // Try to get the next IOM operation from the queue. + // + if ( am_hal_queue_item_get(&g_psIOMQueue[ui32Module], &sIOMTransaction, 1) ) + { + // + // Read the operation parameters + // + ui32ChipSelect = sIOMTransaction.ui32ChipSelect; + pui32Data = sIOMTransaction.pui32Data; + ui32NumBytes = sIOMTransaction.ui32NumBytes; + ui32Options = sIOMTransaction.ui32Options; + pfnCallback = sIOMTransaction.pfnCallback; + + // + // Figure out if this was a SPI or I2C write or read, and call the + // appropriate non-blocking function. + // + switch ( sIOMTransaction.ui32Operation ) + { + case AM_HAL_IOM_QUEUE_SPI_WRITE: + am_hal_iom_spi_write_nb(ui32Module, ui32ChipSelect, pui32Data, + ui32NumBytes, ui32Options, pfnCallback); + break; + + case AM_HAL_IOM_QUEUE_SPI_READ: + am_hal_iom_spi_read_nb(ui32Module, ui32ChipSelect, pui32Data, + ui32NumBytes, ui32Options, pfnCallback); + break; + + case AM_HAL_IOM_QUEUE_I2C_WRITE: + am_hal_iom_i2c_write_nb(ui32Module, ui32ChipSelect, pui32Data, + ui32NumBytes, ui32Options, pfnCallback); + break; + + case AM_HAL_IOM_QUEUE_I2C_READ: + am_hal_iom_i2c_read_nb(ui32Module, ui32ChipSelect, pui32Data, + ui32NumBytes, ui32Options, pfnCallback); + break; + } + } + + // + // Exit the critical section. + // + am_hal_interrupt_master_set(ui32Critical); +} + +//***************************************************************************** +// +//! @brief Send a SPI frame using the IOM queue. +//! +//! @param ui32Module - Module number for the IOM +//! @param ui32ChipSelect - Chip-select number for this transaction. +//! @param pui32Data - Pointer to the bytes that will be sent. +//! @param ui32NumBytes - Number of bytes to send. +//! @param ui32Options - Additional SPI transfer options. +//! +//! This function performs SPI writes to a selected SPI device. +//! +//! This function call is a queued implementation. It will write as much +//! data to the FIFO as possible immediately, store a pointer to the remaining +//! data, start the transfer on the bus, and then immediately return. If the +//! FIFO is already in use, this function will save its arguments to the IOM +//! queue and execute the transaction when the FIFO becomes available. +//! +//! The caller will need to make sure that \e am_hal_iom_queue_service() is +//! called for IOM FIFO interrupt events and "command complete" interrupt +//! events. The \e am_hal_iom_queue_service() function will refill the FIFO as +//! necessary and call the \e pfnCallback function when the transaction is +//! finished. +//! +//! @note The actual SPI and I2C interfaces operate in BYTES, not 32-bit words. +//! This means that you will need to byte-pack the \e pui32Data array with the +//! data you intend to send over the interface. One easy way to do this is to +//! declare the array as a 32-bit integer array, but use an 8-bit pointer to +//! put your actual data into the array. If there are not enough bytes in your +//! desired message to completely fill the last 32-bit word, you may pad that +//! last word with bytes of any value. The IOM hardware will only read the +//! first \e ui32NumBytes in the \e pui8Data array. +// +//***************************************************************************** +void +am_hal_iom_queue_spi_write(uint32_t ui32Module, uint32_t ui32ChipSelect, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options, am_hal_iom_callback_t pfnCallback) +{ + uint32_t ui32Critical; + + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + am_hal_debug_assert_msg(ui32NumBytes > 0, + "Trying to do a 0 byte transaction"); + + // + // Start a critical section. + // + ui32Critical = am_hal_interrupt_master_disable(); + + // + // Check to see if we need to use the queue. If the IOM is idle, and + // there's nothing in the queue already, we can go ahead and start the + // transaction in the physical IOM. Need to check for the g_bIomBusy to + // avoid a race condition where IDLE is set - but the command complete + // for previous transaction has not been processed yet + // + if ( (g_bIomBusy[ui32Module] == false) && + am_hal_queue_empty(&g_psIOMQueue[ui32Module]) ) + { + // + // Send the packet. + // + am_hal_iom_spi_write_nb(ui32Module, ui32ChipSelect, pui32Data, + ui32NumBytes, ui32Options, pfnCallback); + } + else + { + // + // Otherwise, we'll build a transaction structure and add it to the queue. + // + am_hal_iom_queue_entry_t sIOMTransaction; + + sIOMTransaction.ui32Operation = AM_HAL_IOM_QUEUE_SPI_WRITE; + sIOMTransaction.ui32Module = ui32Module; + sIOMTransaction.ui32ChipSelect = ui32ChipSelect; + sIOMTransaction.pui32Data = pui32Data; + sIOMTransaction.ui32NumBytes = ui32NumBytes; + sIOMTransaction.ui32Options = ui32Options; + sIOMTransaction.pfnCallback = pfnCallback; + + // + // Make sure the item actually makes it into the queue + // + if ( am_hal_queue_item_add(&g_psIOMQueue[ui32Module], &sIOMTransaction, 1) == false ) + { + // + // Didn't have enough memory. + // + am_hal_debug_assert_msg(0, + "The IOM queue is full. Allocate more" + "memory to the IOM queue, or allow it more" + "time to empty between transactions."); + } + } + + // + // Exit the critical section. + // + am_hal_interrupt_master_set(ui32Critical); +} + +//***************************************************************************** +// +//! @brief Read a SPI frame using the IOM queue. +//! +//! @param ui32Module - Module number for the IOM +//! @param ui32ChipSelect - Chip select number for this transaction. +//! @param pui32Data - Pointer to the array where received bytes should go. +//! @param ui32NumBytes - Number of bytes to read. +//! @param ui32Options - Additional SPI transfer options. +//! +//! This function performs SPI reads to a selected SPI device. +//! +//! This function call is a queued implementation. It will write as much +//! data to the FIFO as possible immediately, store a pointer to the remaining +//! data, start the transfer on the bus, and then immediately return. If the +//! FIFO is already in use, this function will save its arguments to the IOM +//! queue and execute the transaction when the FIFO becomes available. +//! +//! The caller will need to make sure that \e am_hal_iom_queue_service() is +//! called for IOM FIFO interrupt events and "command complete" interrupt +//! events. The \e am_hal_iom_queue_service() function will empty the FIFO as +//! necessary and call the \e pfnCallback function when the transaction is +//! finished. +//! +//! @note The actual SPI and I2C interfaces operate in BYTES, not 32-bit words. +//! This means that you will need to byte-pack the \e pui32Data array with the +//! data you intend to send over the interface. One easy way to do this is to +//! declare the array as a 32-bit integer array, but use an 8-bit pointer to +//! put your actual data into the array. If there are not enough bytes in your +//! desired message to completely fill the last 32-bit word, you may pad that +//! last word with bytes of any value. The IOM hardware will only read the +//! first \e ui32NumBytes in the \e pui8Data array. +// +//***************************************************************************** +void +am_hal_iom_queue_spi_read(uint32_t ui32Module, uint32_t ui32ChipSelect, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options, am_hal_iom_callback_t pfnCallback) +{ + uint32_t ui32Critical; + + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + am_hal_debug_assert_msg(ui32NumBytes > 0, + "Trying to do a 0 byte transaction"); + + // Start a critical section. + // + ui32Critical = am_hal_interrupt_master_disable(); + + // + // Check to see if we need to use the queue. If the IOM is idle, and + // there's nothing in the queue already, we can go ahead and start the + // transaction in the physical IOM. Need to check for the g_bIomBusy to + // avoid a race condition where IDLE is set - but the command complete + // for previous transaction has not been processed yet + // + if ( (g_bIomBusy[ui32Module] == false) && + am_hal_queue_empty(&g_psIOMQueue[ui32Module]) ) + { + // + // Send the packet. + // + am_hal_iom_spi_read_nb(ui32Module, ui32ChipSelect, pui32Data, + ui32NumBytes, ui32Options, pfnCallback); + } + else + { + // + // Otherwise, we'll build a transaction structure and add it to the queue. + // + am_hal_iom_queue_entry_t sIOMTransaction; + + sIOMTransaction.ui32Operation = AM_HAL_IOM_QUEUE_SPI_READ; + sIOMTransaction.ui32Module = ui32Module; + sIOMTransaction.ui32ChipSelect = ui32ChipSelect; + sIOMTransaction.pui32Data = pui32Data; + sIOMTransaction.ui32NumBytes = ui32NumBytes; + sIOMTransaction.ui32Options = ui32Options; + sIOMTransaction.pfnCallback = pfnCallback; + + // + // Make sure the item actually makes it into the queue + // + if ( am_hal_queue_item_add(&g_psIOMQueue[ui32Module], &sIOMTransaction, 1) == false ) + { + // + // Didn't have enough memory. + // + am_hal_debug_assert_msg(0, + "The IOM queue is full. Allocate more" + "memory to the IOM queue, or allow it more" + "time to empty between transactions."); + } + } + + // + // Exit the critical section. + // + am_hal_interrupt_master_set(ui32Critical); +} + +//***************************************************************************** +// +//! @brief Send an I2C frame using the IOM queue. +//! +//! @param ui32Module - Module number for the IOM +//! @param ui32BusAddress - I2C address of the target device. +//! @param pui32Data - Pointer to the bytes that will be sent. +//! @param ui32NumBytes - Number of bytes to send. +//! @param ui32Options - Additional I2C transfer options. +//! +//! This function performs I2C writes to a selected I2C device. +//! +//! This function call is a queued implementation. It will write as much +//! data to the FIFO as possible immediately, store a pointer to the remaining +//! data, start the transfer on the bus, and then immediately return. If the +//! FIFO is already in use, this function will save its arguments to the IOM +//! queue and execute the transaction when the FIFO becomes available. +//! +//! The caller will need to make sure that \e am_hal_iom_queue_service() is +//! called for IOM FIFO interrupt events and "command complete" interrupt +//! events. The \e am_hal_iom_queue_service() function will refill the FIFO as +//! necessary and call the \e pfnCallback function when the transaction is +//! finished. +//! +//! @note The actual SPI and I2C interfaces operate in BYTES, not 32-bit words. +//! This means that you will need to byte-pack the \e pui32Data array with the +//! data you intend to send over the interface. One easy way to do this is to +//! declare the array as a 32-bit integer array, but use an 8-bit pointer to +//! put your actual data into the array. If there are not enough bytes in your +//! desired message to completely fill the last 32-bit word, you may pad that +//! last word with bytes of any value. The IOM hardware will only read the +//! first \e ui32NumBytes in the \e pui8Data array. +// +//***************************************************************************** +void +am_hal_iom_queue_i2c_write(uint32_t ui32Module, uint32_t ui32BusAddress, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options, am_hal_iom_callback_t pfnCallback) +{ + uint32_t ui32Critical; + + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + am_hal_debug_assert_msg(ui32NumBytes > 0, + "Trying to do a 0 byte transaction"); + + // + // Start a critical section. + // + ui32Critical = am_hal_interrupt_master_disable(); + + // + // Check to see if we need to use the queue. If the IOM is idle, and + // there's nothing in the queue already, we can go ahead and start the + // transaction in the physical IOM. Need to check for the g_bIomBusy to + // avoid a race condition where IDLE is set - but the command complete + // for previous transaction has not been processed yet + // + if ( (g_bIomBusy[ui32Module] == false) && + am_hal_queue_empty(&g_psIOMQueue[ui32Module]) ) + { + // + // Send the packet. + // + am_hal_iom_i2c_write_nb(ui32Module, ui32BusAddress, pui32Data, + ui32NumBytes, ui32Options, pfnCallback); + } + else + { + // + // Otherwise, we'll build a transaction structure and add it to the queue. + // + am_hal_iom_queue_entry_t sIOMTransaction; + + sIOMTransaction.ui32Operation = AM_HAL_IOM_QUEUE_I2C_WRITE; + sIOMTransaction.ui32Module = ui32Module; + sIOMTransaction.ui32ChipSelect = ui32BusAddress; + sIOMTransaction.pui32Data = pui32Data; + sIOMTransaction.ui32NumBytes = ui32NumBytes; + sIOMTransaction.ui32Options = ui32Options; + sIOMTransaction.pfnCallback = pfnCallback; + + // + // Make sure the item actually makes it into the queue + // + if ( am_hal_queue_item_add(&g_psIOMQueue[ui32Module], &sIOMTransaction, 1) == false ) + { + // + // Didn't have enough memory. + // + am_hal_debug_assert_msg(0, + "The IOM queue is full. Allocate more" + "memory to the IOM queue, or allow it more" + "time to empty between transactions."); + } + } + + // + // Exit the critical section. + // + am_hal_interrupt_master_set(ui32Critical); +} + +//***************************************************************************** +// +//! @brief Read a I2C frame using the IOM queue. +//! +//! @param ui32Module - Module number for the IOM +//! @param ui32BusAddress - I2C address of the target device. +//! @param pui32Data - Pointer to the array where received bytes should go. +//! @param ui32NumBytes - Number of bytes to read. +//! @param ui32Options - Additional I2C transfer options. +//! +//! This function performs I2C reads to a selected I2C device. +//! +//! This function call is a queued implementation. It will write as much +//! data to the FIFO as possible immediately, store a pointer to the remaining +//! data, start the transfer on the bus, and then immediately return. If the +//! FIFO is already in use, this function will save its arguments to the IOM +//! queue and execute the transaction when the FIFO becomes available. +//! +//! The caller will need to make sure that \e am_hal_iom_queue_service() is +//! called for IOM FIFO interrupt events and "command complete" interrupt +//! events. The \e am_hal_iom_queue_service() function will empty the FIFO as +//! necessary and call the \e pfnCallback function when the transaction is +//! finished. +//! +//! @note The actual SPI and I2C interfaces operate in BYTES, not 32-bit words. +//! This means that you will need to byte-pack the \e pui32Data array with the +//! data you intend to send over the interface. One easy way to do this is to +//! declare the array as a 32-bit integer array, but use an 8-bit pointer to +//! put your actual data into the array. If there are not enough bytes in your +//! desired message to completely fill the last 32-bit word, you may pad that +//! last word with bytes of any value. The IOM hardware will only read the +//! first \e ui32NumBytes in the \e pui8Data array. +// +//***************************************************************************** +void +am_hal_iom_queue_i2c_read(uint32_t ui32Module, uint32_t ui32BusAddress, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options, am_hal_iom_callback_t pfnCallback) +{ + uint32_t ui32Critical; + + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + am_hal_debug_assert_msg(ui32NumBytes > 0, + "Trying to do a 0 byte transaction"); + + // + // Start a critical section. + // + ui32Critical = am_hal_interrupt_master_disable(); + + // + // Check to see if we need to use the queue. If the IOM is idle, and + // there's nothing in the queue already, we can go ahead and start the + // transaction in the physical IOM. Need to check for the g_bIomBusy to + // avoid a race condition where IDLE is set - but the command complete + // for previous transaction has not been processed yet + // + if ( (g_bIomBusy[ui32Module] == false) && + am_hal_queue_empty(&g_psIOMQueue[ui32Module]) ) + { + // + // Send the packet. + // + am_hal_iom_i2c_read_nb(ui32Module, ui32BusAddress, pui32Data, + ui32NumBytes, ui32Options, pfnCallback); + } + else + { + // + // Otherwise, we'll build a transaction structure and add it to the queue. + // + am_hal_iom_queue_entry_t sIOMTransaction; + + sIOMTransaction.ui32Operation = AM_HAL_IOM_QUEUE_I2C_READ; + sIOMTransaction.ui32Module = ui32Module; + sIOMTransaction.ui32ChipSelect = ui32BusAddress; + sIOMTransaction.pui32Data = pui32Data; + sIOMTransaction.ui32NumBytes = ui32NumBytes; + sIOMTransaction.ui32Options = ui32Options; + sIOMTransaction.pfnCallback = pfnCallback; + + // + // Make sure the item actually makes it into the queue + // + if ( am_hal_queue_item_add(&g_psIOMQueue[ui32Module], &sIOMTransaction, 1) == false ) + { + // + // Didn't have enough memory. + // + am_hal_debug_assert_msg(0, "The IOM queue is full. Allocate more" + "memory to the IOM queue, or allow it more" + "time to empty between transactions."); + } + } + + // + // Exit the critical section. + // + am_hal_interrupt_master_set(ui32Critical); +} + +//***************************************************************************** +// +//! @brief "Block" until the queue of IOM transactions is over. +//! +//! @param ui32Module - Module number for the IOM. +//! +//! This function will sleep the core block until the queue for the selected +//! IOM is empty. This is mainly useful for non-RTOS applications where the +//! caller needs to know that a certain IOM transaction is complete before +//! continuing with the main program flow. +//! +//! @note This function will put the core to sleep while it waits for the +//! queued IOM transactions to complete. This will save power, in most +//! situations, but it may not be the best option in all cases. \e Do \e not +//! call this function from interrupt context (the core may not wake up again). +//! \e Be \e careful using this function from an RTOS task (many RTOS +//! implementations use hardware interrupts to switch contexts, and most RTOS +//! implementations expect to control sleep behavior). +// +//***************************************************************************** +void +am_hal_iom_sleeping_queue_flush(uint32_t ui32Module) +{ + bool bWaiting = true; + uint32_t ui32Critical; + + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + + // + // Loop forever waiting for the IOM to be idle and the queue to be empty. + // + while ( bWaiting ) + { + // + // Start a critical section. + // + ui32Critical = am_hal_interrupt_master_disable(); + + // + // Check the queue and the IOM itself. + // + if ( (g_bIomBusy[ui32Module] == false) && + am_hal_queue_empty(&g_psIOMQueue[ui32Module]) ) + { + // + // If the queue is empty and the IOM is idle, we can go ahead and + // return. + // + bWaiting = false; + } + else + { + // + // Otherwise, we should sleep until the interface is actually free. + // + am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_NORMAL); + } + + // + // End the critical section. + // + am_hal_interrupt_master_set(ui32Critical); + } +} + +//***************************************************************************** +// +//! @brief Service IOM transaction queue. +//! +//! @param ui32Module - Module number for the IOM to be used. +//! @param ui32Status - Interrupt status bits for the IOM module being used. +//! +//! This function handles the operation of FIFOs and the IOM queue during +//! queued IOM transactions. If you are using \e am_hal_iom_queue_spi_write() +//! or similar functions, you will need to call this function in your interrupt +//! handler. +//! +//! @note This interrupt service routine relies on the user to enable the IOM +//! interrupts for FIFO threshold and CMD complete. +//! +//! Example: +//! +//! @code +//! void +//! am_iomaster0_isr(void) +//! { +//! uint32_t ui32Status; +//! +//! // +//! // Check to see which interrupt caused us to enter the ISR. +//! // +//! ui32Status = am_hal_iom_int_status(0, true); +//! +//! // +//! // Fill or empty the FIFO, and either continue the current operation or +//! // start the next one in the queue. If there was a callback, it will be +//! // called here. +//! // +//! am_hal_iom_queue_service(0, ui32Status); +//! +//! // +//! // Clear the interrupts before leaving the ISR. +//! // +//! am_hal_iom_int_clear(ui32Status); +//! } +//! @endcode +//! +//! @return +// +//***************************************************************************** +void +am_hal_iom_queue_service(uint32_t ui32Module, uint32_t ui32Status) +{ + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + + // + // Service the FIFOs in case this was a threshold interrupt. + // + am_hal_iom_int_service(ui32Module, ui32Status); + + // + // If the last interrupt was a "command complete", then the IOM should be + // idle already or very soon. Make absolutely sure that the IOM is not in + // use, and then start the next transaction in the queue. + // + if ( ui32Status & AM_HAL_IOM_INT_CMDCMP ) + { + if ( g_psIOMQueue[ui32Module].pui8Data != NULL ) + { + am_hal_iom_queue_start_next_msg(ui32Module); + } + } +} + +//***************************************************************************** +// +//! @brief Enable selected IOM Interrupts. +//! +//! @param ui32Module - Module number. +//! @param ui32Interrupt - Use the macro bit fields provided in am_hal_iom.h +//! +//! Use this function to enable the IOM interrupts. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_iom_int_enable(uint32_t ui32Module, uint32_t ui32Interrupt) +{ + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + + AM_REGn(IOMSTR, ui32Module, INTEN) |= ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Return the enabled IOM Interrupts. +//! +//! @param ui32Module - Module number. +//! +//! Use this function to return all enabled IOM interrupts. +//! +//! @return all enabled IOM interrupts. +// +//***************************************************************************** +uint32_t +am_hal_iom_int_enable_get(uint32_t ui32Module) +{ + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return 0; + } + + return AM_REGn(IOMSTR, ui32Module, INTEN); +} + +//***************************************************************************** +// +//! @brief Disable selected IOM Interrupts. +//! +//! @param ui32Module - Module number. +//! @param ui32Interrupt - Use the macro bit fields provided in am_hal_iom.h +//! +//! Use this function to disable the IOM interrupts. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_iom_int_disable(uint32_t ui32Module, uint32_t ui32Interrupt) +{ + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + + AM_REGn(IOMSTR, ui32Module, INTEN) &= ~ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Clear selected IOM Interrupts. +//! +//! @param ui32Module - Module number. +//! @param ui32Interrupt - Use the macro bit fields provided in am_hal_iom.h +//! +//! Use this function to clear the IOM interrupts. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_iom_int_clear(uint32_t ui32Module, uint32_t ui32Interrupt) +{ + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + + AM_REGn(IOMSTR, ui32Module, INTCLR) = ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Set selected IOM Interrupts. +//! +//! @param ui32Module - Module number. +//! @param ui32Interrupt - Use the macro bit fields provided in am_hal_iom.h +//! +//! Use this function to set the IOM interrupts. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_iom_int_set(uint32_t ui32Module, uint32_t ui32Interrupt) +{ + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return; + } + + AM_REGn(IOMSTR, ui32Module, INTSET) = ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Return the IOM Interrupt status. +//! +//! @param ui32Module - Module number. +//! @param bEnabledOnly - return only the enabled interrupts. +//! +//! Use this function to get the IOM interrupt status. +//! +//! @return interrupt status +// +//***************************************************************************** +uint32_t +am_hal_iom_int_status_get(uint32_t ui32Module, bool bEnabledOnly) +{ + // + // Validate parameters + // + if ( ui32Module >= AM_REG_IOMSTR_NUM_MODULES ) + { + return 0; + } + + if ( bEnabledOnly ) + { + uint32_t u32RetVal = AM_REGn(IOMSTR, ui32Module, INTSTAT); + return u32RetVal & AM_REGn(IOMSTR, ui32Module, INTEN); + } + else + { + return AM_REGn(IOMSTR, ui32Module, INTSTAT); + } +} + + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_iom.h b/bsp/apollo2/libraries/drivers/hal/am_hal_iom.h new file mode 100644 index 0000000000..e5a450f15c --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_iom.h @@ -0,0 +1,559 @@ +//***************************************************************************** +// +// am_hal_iom.h +//! @file +//! +//! @brief Functions for accessing and configuring the IO Master module +//! +//! @addtogroup iom2 IO Master (SPI/I2C) +//! @ingroup apollo2hal +//! @{ + +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#ifndef AM_HAL_IOM_H +#define AM_HAL_IOM_H + +//***************************************************************************** +// +// Macro definitions +// +//***************************************************************************** + +//***************************************************************************** +// +//! @name IOM Clock Frequencies +//! @brief Macro definitions for common SPI and I2C clock frequencies. +//! +//! These macros may be used with the ui32ClockFrequency member of the +//! am_hal_iom_config_t structure to set the clock frequency of the serial +//! interfaces. +//! +//! This list of frequencies is not exhaustive by any means. If your desired +//! frequency is not in this list, simply set ui32ClockFrequency to the +//! desired frequency (in Hz) when calling am_hal_iom_config(). +// +//***************************************************************************** +#define AM_HAL_IOM_24MHZ 24000000 +#define AM_HAL_IOM_16MHZ 16000000 +#define AM_HAL_IOM_12MHZ 12000000 +#define AM_HAL_IOM_8MHZ 8000000 +#define AM_HAL_IOM_6MHZ 6000000 +#define AM_HAL_IOM_4MHZ 4000000 +#define AM_HAL_IOM_3MHZ 3000000 +#define AM_HAL_IOM_2MHZ 2000000 +#define AM_HAL_IOM_1_5MHZ 1500000 +#define AM_HAL_IOM_1MHZ 1000000 +#define AM_HAL_IOM_750KHZ 750000 +#define AM_HAL_IOM_500KHZ 500000 +#define AM_HAL_IOM_400KHZ 400000 +#define AM_HAL_IOM_375KHZ 375000 +#define AM_HAL_IOM_250KHZ 250000 +#define AM_HAL_IOM_125KHZ 125000 +#define AM_HAL_IOM_100KHZ 100000 +#define AM_HAL_IOM_50KHZ 50000 +#define AM_HAL_IOM_10KHZ 10000 + +// Hardware FIFO Size +#define AM_HAL_IOM_MAX_FIFO_SIZE 128 + +//***************************************************************************** +// +//! @name IOM Physical Protocols +//! @brief Macro Definitions for general IOM configuration. +//! +//! These macros may be used with the am_hal_iom_config_t structure to set the +//! operating parameters of each serial IO master module. Choose SPIMODE to +//! select the SPI interface, or I2CMODE to select the I2C interface. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_IOM_SPIMODE AM_REG_IOMSTR_CFG_IFCSEL(1) +#define AM_HAL_IOM_I2CMODE AM_REG_IOMSTR_CFG_IFCSEL(0) +//! @} + +//***************************************************************************** +// +//! @name IOM Operations +//! @brief Macro definitions used for ui32Operation parameters. +//! +//! These macros may be used to specify which action an IOM command will +//! execute. The 'OFFSET' operations will cause the IOM hardware to transmit the +//! provided 1-byte 'offset' before executing the rest of the command. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_IOM_WRITE 0x00000000 +#define AM_HAL_IOM_READ 0x80000000 +//! @} + +//***************************************************************************** +// +//! @name Command Options +//! @brief Macro definitions used for ui32Options parameters. +//! +//! These macros are all related to SPI or I2C command words. They can be used +//! to set specific options on a per-transaction basis. +//! +//! - CS_LOW - Do not raise the CS signal at the end of this SPI command. +//! - NO_STOP - Do not release the I2C bus with a STOP bit after this command. +//! - LSB_FIRST - Reverse the payload bits of this command. +//! - 10BIT_ADDRESS - (I2C only) use a 10-bit I2C address protocol. +//! - RAW - Don't use an offset byte. +//! - OFFSET() - Send this 1-byte offset as the first byte of the transaction. +//! This can be used to access "registers" in external I2C devices, or add a +//! 1-byte write to the beginning of a SPI write or read command. See +//! "normal mode" operation in the I2C/SPI Master section of the datasheet +//! for more information on this parameter. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_IOM_CS_LOW 0x10000000 +#define AM_HAL_IOM_NO_STOP 0x10000000 +#define AM_HAL_IOM_LSB_FIRST 0x08000000 +#define AM_HAL_IOM_10BIT_ADDRESS 0x04000000 +#define AM_HAL_IOM_RAW 0x40000000 +#define AM_HAL_IOM_OFFSET(n) (((n) << 8) & 0x0000FF00) +//! @} + +//***************************************************************************** +// +//! @name IOM Interrupts +//! @brief Macro definitions for IOM interrupt status bits. +//! +//! These macros correspond to the bits in the IOM interrupt status register. +//! They may be used with any of the \e am_hal_iom_int_x() functions. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_IOM_INT_ARB AM_REG_IOMSTR_INTEN_ARB_M +#define AM_HAL_IOM_INT_STOP AM_REG_IOMSTR_INTEN_STOP_M +#define AM_HAL_IOM_INT_START AM_REG_IOMSTR_INTEN_START_M +#define AM_HAL_IOM_INT_ICMD AM_REG_IOMSTR_INTEN_ICMD_M +#define AM_HAL_IOM_INT_IACC AM_REG_IOMSTR_INTEN_IACC_M +#define AM_HAL_IOM_INT_WTLEN AM_REG_IOMSTR_INTEN_WTLEN_M +#define AM_HAL_IOM_INT_NAK AM_REG_IOMSTR_INTEN_NAK_M +#define AM_HAL_IOM_INT_FOVFL AM_REG_IOMSTR_INTEN_FOVFL_M +#define AM_HAL_IOM_INT_FUNDFL AM_REG_IOMSTR_INTEN_FUNDFL_M +#define AM_HAL_IOM_INT_THR AM_REG_IOMSTR_INTEN_THR_M +#define AM_HAL_IOM_INT_CMDCMP AM_REG_IOMSTR_INTEN_CMDCMP_M +//! @} + +//***************************************************************************** +// +//! @name IOM function errors +//! @brief Return values for IOM HAL function errors, such as with the function +//! am_hal_iom_error_status_get(). +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_IOM_ERR_INVALID_MODULE (1 << 30) +//! @} + +//***************************************************************************** +// +//! @name Software IOM modules +//! @brief Macro definitions for using the software I2C interface. +//! +//! Use this macro as the module number for standard IOM functions to emulate +//! them using the bit-banged i2c interface. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_IOM_I2CBB_MODULE AM_REG_IOMSTR_NUM_MODULES +//! @} + +//***************************************************************************** +// +//! @brief Union type for a word-aligned, byte-addressable array. +//! +//! This is a convenience macro that may be used to define byte-addressable +//! arrays with 32-bit alignment. This allows the programmer to define SPI or +//! I2C transactions as a series of 8-bit values, but also write them to the +//! IOM FIFO efficiently as a series of 32-bit values. +//! +//! Example usage: +//! +//! @code +//! // +//! // Declare a buffer array with at least 3-bytes worth of space. +//! // +//! am_hal_iom_buffer(3) sBuffer; +//! +//! // +//! // Populate the buffer with a 3-byte command. +//! // +//! sBuffer.bytes[0] = 's'; +//! sBuffer.bytes[1] = 'p'; +//! sBuffer.bytes[2] = 'i'; +//! +//! // +//! // Send the buffer over the spi interface. +//! // +//! am_hal_iom_spi_write(psDevice, sBuffer.words, 3, 0); +//! +//! @endcode +// +//***************************************************************************** +#define am_hal_iom_buffer(A) \ + union \ + { \ + uint32_t words[(A + 3) >> 2]; \ + uint8_t bytes[A]; \ + } + +//***************************************************************************** +// +//! @brief Configuration structure for the IO master module. +// +//***************************************************************************** +typedef struct +{ + // + //! @brief Selects the physical protocol for the IO master module. Choose + //! either AM_HAL_IOM_SPIMODE or AM_HAL_IOM_I2CMODE. + // + uint32_t ui32InterfaceMode; + + // + //! @brief Selects the output clock frequency for SPI or I2C mode. Choose + //! one of the AM_HAL_IOM_nMHZ or AM_HAL_IOM_nKHZ macros. + // + uint32_t ui32ClockFrequency; + + // + //! Select the SPI clock phase (unused in I2C mode). + // + bool bSPHA; + + // + //! Select the SPI clock polarity (unused in I2C mode). + // + bool bSPOL; + + // + //! @brief Select the FIFO write threshold. + //! + //! The IOM controller will generate a processor interrupt when the number + //! of entries in the FIFO goes *below* this number. + // + uint8_t ui8WriteThreshold; + + // + //! @brief Select the FIFO read threshold. + //! + //! The IOM controller will generate a processor interrupt when the number + //! of entries in the FIFO grows *larger* than this number. + // + uint8_t ui8ReadThreshold; + +} +am_hal_iom_config_t; + +//***************************************************************************** +// +//! Configuration structure for an individual SPI device. +// +//***************************************************************************** +typedef struct +{ + // + //! IOM module to use for communicating with this device. + // + uint32_t ui32Module; + + // + //! Chip select signal that should be used for this device. + // + uint32_t ui32ChipSelect; + + // + //! Additional options that will ALWAYS be ORed into the command word. + // + uint32_t ui32Options; +} +am_hal_iom_spi_device_t; + +//***************************************************************************** +// +//! Configuration structure for an individual I2C device. +// +//***************************************************************************** +typedef struct +{ + // + //! IOM module to use for communicating with this device. + // + uint32_t ui32Module; + + // + //! I2C address associated with this device. + // + uint32_t ui32BusAddress; + + // + //! Additional options that will ALWAYS be ORed into the command word. + // + uint32_t ui32Options; +} +am_hal_iom_i2c_device_t; + +//***************************************************************************** +// +// Typedef for non-blocking function callbacks. +// +//***************************************************************************** +typedef void (*am_hal_iom_callback_t)(void); + +//***************************************************************************** +// +// Typedef for a function that waits until the IOM queue is empty. +// +//***************************************************************************** +typedef void (*am_hal_iom_queue_flush_t)(uint32_t); + +extern am_hal_iom_queue_flush_t am_hal_iom_queue_flush; + + +//***************************************************************************** +// +// Operations +// +//***************************************************************************** +#define AM_HAL_IOM_QUEUE_SPI_WRITE 0 +#define AM_HAL_IOM_QUEUE_SPI_READ 1 +#define AM_HAL_IOM_QUEUE_I2C_WRITE 2 +#define AM_HAL_IOM_QUEUE_I2C_READ 3 + +//***************************************************************************** +// +// Structure to hold IOM operations. +// +//***************************************************************************** +typedef struct +{ + uint32_t ui32Operation; + uint32_t ui32Module; + uint32_t ui32ChipSelect; + uint32_t *pui32Data; + uint32_t ui32NumBytes; + uint32_t ui32Options; + am_hal_iom_callback_t pfnCallback; +} +am_hal_iom_queue_entry_t; + +//***************************************************************************** +// +// Structure to hold IOM configuration during module power-down. +// +//***************************************************************************** +typedef struct +{ + uint32_t FIFOTHR; + uint32_t CLKCFG; + uint32_t CFG; + uint32_t INTEN; + uint32_t bValid; +} +am_hal_iom_pwrsave_t; + +//***************************************************************************** +// +// Global variables +// +//***************************************************************************** +extern am_hal_iom_pwrsave_t am_hal_iom_pwrsave[AM_REG_IOMSTR_NUM_MODULES]; +extern uint32_t g_iom_error_status; + +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern void am_hal_iom_pwrctrl_enable(uint32_t ui32Module); +extern void am_hal_iom_pwrctrl_disable(uint32_t ui32Module); +extern void am_hal_iom_power_on_restore(uint32_t ui32Module); +extern void am_hal_iom_power_off_save(uint32_t ui32Module); +extern void am_hal_iom_config(uint32_t ui32Module, + const am_hal_iom_config_t *psConfig); +extern uint32_t am_hal_iom_frequency_get(uint32_t ui32Module); +extern void am_hal_iom_enable(uint32_t ui32Module); +extern void am_hal_iom_disable(uint32_t ui32Module); +extern void am_hal_iom_spi_write(uint32_t ui32Module, uint32_t ui32ChipSelect, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options); +extern void am_hal_iom_spi_read(uint32_t ui32Module, uint32_t ui32ChipSelect, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options); +extern uint32_t am_hal_iom_spi_write_nq(uint32_t ui32Module, uint32_t ui32ChipSelect, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options); +extern uint32_t am_hal_iom_spi_read_nq(uint32_t ui32Module, uint32_t ui32ChipSelect, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options); +extern void am_hal_iom_spi_write_nb(uint32_t ui32Module, uint32_t ui32ChipSelect, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options, + am_hal_iom_callback_t pfnCallback); +extern uint32_t am_hal_iom_spi_read_nb(uint32_t ui32Module, uint32_t ui32ChipSelect, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options, + am_hal_iom_callback_t pfnCallback); +extern void am_hal_iom_spi_cmd_run(uint32_t ui32Operation, + uint32_t ui32Module, + uint32_t ui32ChipSelect, + uint32_t ui32NumBytes, + uint32_t ui32Options); +extern void am_hal_iom_i2c_write(uint32_t ui32Module, + uint32_t ui32BusAddress, + uint32_t *pui32Data, + uint32_t ui32NumBytes, + uint32_t ui32Options); +extern void am_hal_iom_i2c_read(uint32_t ui32Module, + uint32_t ui32BusAddress, + uint32_t *pui32Data, + uint32_t ui32NumBytes, + uint32_t ui32Options); +extern uint32_t am_hal_iom_i2c_write_nq(uint32_t ui32Module, + uint32_t ui32BusAddress, + uint32_t *pui32Data, + uint32_t ui32NumBytes, + uint32_t ui32Options); +extern uint32_t am_hal_iom_i2c_read_nq(uint32_t ui32Module, + uint32_t ui32BusAddress, + uint32_t *pui32Data, + uint32_t ui32NumBytes, + uint32_t ui32Options); +extern void am_hal_iom_i2c_write_nb(uint32_t ui32Module, + uint32_t ui32BusAddress, + uint32_t *pui32Data, + uint32_t ui32NumBytes, + uint32_t ui32Options, + am_hal_iom_callback_t pfnCallback); +extern void am_hal_iom_i2c_read_nb(uint32_t ui32Module, + uint32_t ui32BusAddress, + uint32_t *pui32Data, + uint32_t ui32NumBytes, + uint32_t ui32Options, + am_hal_iom_callback_t pfnCallback); +extern void am_hal_iom_i2c_cmd_run(uint32_t ui32Operation, + uint32_t ui32Module, + uint32_t ui32BusAddress, + uint32_t ui32NumBytes, + uint32_t ui32Options); +extern void am_hal_iom_command_repeat_set(uint32_t ui32Module, + uint32_t ui32CmdCount); +extern uint32_t am_hal_iom_status_get(uint32_t ui32Module); +extern uint32_t am_hal_iom_error_status_get(uint32_t ui32Module); +extern uint32_t am_hal_iom_fifo_write(uint32_t ui32Module, uint32_t *pui32Data, + uint32_t ui32NumBytes); +extern uint32_t am_hal_iom_fifo_read(uint32_t ui32Module, uint32_t *pui32Data, + uint32_t ui32NumBytes); +extern uint8_t am_hal_iom_fifo_empty_slots(uint32_t ui32Module); +extern uint8_t am_hal_iom_fifo_full_slots(uint32_t ui32Module); +extern void am_hal_iom_poll_complete(uint32_t ui32Module); +extern void am_hal_iom_int_service(uint32_t ui32Module, uint32_t ui32Status); +extern void am_hal_iom_int_enable(uint32_t ui32Module, uint32_t ui32Interrupt); +extern uint32_t am_hal_iom_int_enable_get(uint32_t ui32Module); +extern void am_hal_iom_int_disable(uint32_t ui32Module, uint32_t ui32Interrupt); +extern void am_hal_iom_int_clear(uint32_t ui32Module, uint32_t ui32Interrupt); +extern void am_hal_iom_int_set(uint32_t ui32Module, uint32_t ui32Interrupt); +extern uint32_t am_hal_iom_int_status_get(uint32_t ui32Module, bool bEnabledOnly); +extern void am_hal_iom_queue_init(uint32_t ui32ModuleNum, + am_hal_iom_queue_entry_t *psQueueMemory, + uint32_t ui32QueueMemSize); +extern uint32_t am_hal_iom_queue_length_get(uint32_t ui32Module); +extern void am_hal_iom_sleeping_queue_flush(uint32_t ui32Module); +extern void am_hal_iom_queue_spi_write(uint32_t ui32Module, uint32_t ui32ChipSelect, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options, + am_hal_iom_callback_t pfnCallback); +extern void am_hal_iom_queue_spi_read(uint32_t ui32Module, uint32_t ui32ChipSelect, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options, + am_hal_iom_callback_t pfnCallback); +extern void am_hal_iom_queue_i2c_write(uint32_t ui32Module, uint32_t ui32BusAddress, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options, + am_hal_iom_callback_t pfnCallback); +extern void am_hal_iom_queue_i2c_read(uint32_t ui32Module, uint32_t ui32BusAddress, + uint32_t *pui32Data, uint32_t ui32NumBytes, + uint32_t ui32Options, + am_hal_iom_callback_t pfnCallback); +extern void am_hal_iom_queue_start_next_msg(uint32_t ui32Module); +extern void am_hal_iom_queue_service(uint32_t ui32Module, uint32_t ui32Status); + +//***************************************************************************** +// +// Helper functions. +// +//***************************************************************************** +#define AM_IOMASTER_ISR_QUEUE(x) \ +void am_iomaster##x##_isr(void) \ +{ \ + uint32_t ui32IntStatus; \ + g_iom_error_status = am_hal_iom_error_status_get(x); \ + ui32IntStatus = am_hal_iom_int_status_get(x, false); \ + am_hal_iom_int_clear(x, ui32IntStatus); \ + am_hal_iom_queue_service(x, ui32IntStatus); \ +} + +#define AM_IOMASTER_ISR_NB(x) \ +void am_iomaster##x##_isr(void) \ +{ \ + uint32_t ui32IntStatus; \ + g_iom_error_status = am_hal_iom_error_status_get(x); \ + ui32IntStatus = am_hal_iom_int_status_get(x, false); \ + am_hal_iom_int_clear(x, ui32IntStatus); \ + am_hal_iom_int_service(x, ui32IntStatus); \ +} + +#endif // AM_HAL_IOM_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_ios.c b/bsp/apollo2/libraries/drivers/hal/am_hal_ios.c new file mode 100644 index 0000000000..0f34aa6efb --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_ios.c @@ -0,0 +1,1303 @@ +//***************************************************************************** +// +// am_hal_ios.c +//! @file +//! +//! @brief Functions for interfacing with the IO Slave module +//! +//! @addtogroup ios2 IO Slave (SPI/I2C) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +// SRAM Buffer structure +// +//***************************************************************************** +typedef struct +{ + uint8_t *pui8Data; + volatile uint32_t ui32WriteIndex; + volatile uint32_t ui32ReadIndex; + volatile uint32_t ui32Length; + uint32_t ui32Capacity; +} +am_hal_ios_buffer_t; + +am_hal_ios_buffer_t g_sSRAMBuffer; + +//***************************************************************************** +// +// Forward declarations of static funcitons. +// +//***************************************************************************** +static void am_hal_ios_buffer_init(am_hal_ios_buffer_t *psBuffer, + void *pvArray, uint32_t ui32Bytes); + +static void fifo_write(uint8_t *pui8Data, uint32_t ui32NumBytes); + +//***************************************************************************** +// +// Function-like macros. +// +//***************************************************************************** +#define am_hal_ios_buffer_empty(psBuffer) \ + ((psBuffer)->ui32Length == 0) + +#define am_hal_ios_buffer_full(psBuffer) \ + ((psBuffer)->ui32Length == (psBuffer)->ui32Capacity) + +#define am_hal_ios_buffer_data_left(psBuffer) \ + ((psBuffer)->ui32Length) + +//***************************************************************************** +// +// Global Variables +// +//***************************************************************************** +volatile uint8_t * const am_hal_ios_pui8LRAM = (uint8_t *)REG_IOSLAVE_BASEADDR; +uint8_t *g_pui8FIFOBase = (uint8_t *) REG_IOSLAVE_BASEADDR; +uint8_t *g_pui8FIFOEnd = (uint8_t *) REG_IOSLAVE_BASEADDR; +uint8_t *g_pui8FIFOPtr = (uint8_t *) REG_IOSLAVE_BASEADDR; +uint8_t g_ui32HwFifoSize = 0; +uint32_t g_ui32FifoBaseOffset = 0; + +//***************************************************************************** +// +//! @brief Enable the IOS in the power control block. +//! +//! This function enables the IOS module in the power control block. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_pwrctrl_enable(void) +{ + am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_IOS); +} + +//***************************************************************************** +// +//! @brief Disable the IOS in the power control block. +//! +//! This function disables the IOS module in the power control block. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_pwrctrl_disable(void) +{ + am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_IOS); +} + +//***************************************************************************** +// +//! @brief Enables the IOS module +//! +//! This function enables the IOSLAVE module using the IFCEN bitfield in the +//! IOSLAVE_CFG register. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_enable(uint32_t ui32Module) +{ + AM_REGn(IOSLAVE, ui32Module, CFG) |= AM_REG_IOSLAVE_CFG_IFCEN(1); +} + +//***************************************************************************** +// +//! @brief Disables the IOSLAVE module. +//! +//! This function disables the IOSLAVE module using the IFCEN bitfield in the +//! IOSLAVE_CFG register. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_disable(uint32_t ui32Module) +{ + AM_REGn(IOSLAVE, ui32Module, CFG) &= ~(AM_REG_IOSLAVE_CFG_IFCEN(1)); +} + +//***************************************************************************** +// +//! @brief Configure the IOS module. +//! +//! This function reads the an \e am_hal_ios_config_t structure and uses it to +//! set up the IO Slave module. Please see the information on the configuration +//! structure for more information on the parameters that may be set by this +//! function. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_config(am_hal_ios_config_t *psConfig) +{ + uint32_t ui32LRAMConfig; + + am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_IOS); + + // + // Record the FIFO parameters for later use. + // + g_pui8FIFOBase = (uint8_t *)(REG_IOSLAVE_BASEADDR + psConfig->ui32FIFOBase); + g_pui8FIFOEnd = (uint8_t *)(REG_IOSLAVE_BASEADDR + psConfig->ui32RAMBase); + g_ui32HwFifoSize = g_pui8FIFOEnd - g_pui8FIFOBase; + g_ui32FifoBaseOffset = psConfig->ui32FIFOBase; + + // + // Caluclate the value for the IO Slave FIFO configuration register. + // + ui32LRAMConfig = AM_REG_IOSLAVE_FIFOCFG_ROBASE(psConfig->ui32ROBase >> 3); + ui32LRAMConfig |= AM_REG_IOSLAVE_FIFOCFG_FIFOBASE(psConfig->ui32FIFOBase >> 3); + ui32LRAMConfig |= AM_REG_IOSLAVE_FIFOCFG_FIFOMAX(psConfig->ui32RAMBase >> 3); + + // + // Just in case, disable the IOS + // + am_hal_ios_disable(0); + + // + // Write the configuration register with the user's selected interface + // characteristics. + // + AM_REG(IOSLAVE, CFG) = psConfig->ui32InterfaceSelect; + + // + // Write the FIFO configuration register to set the memory map for the LRAM. + // + AM_REG(IOSLAVE, FIFOCFG) = ui32LRAMConfig; + + // + // Enable the IOS. The following configuration options can't be set while + // the IOS is disabled. + // + am_hal_ios_enable(0); + + // + // Initialize the FIFO pointer to the beginning of the FIFO section. + // + am_hal_ios_fifo_ptr_set(psConfig->ui32FIFOBase); + + // + // Write the FIFO threshold register. + // + AM_REG(IOSLAVE, FIFOTHR) = psConfig->ui32FIFOThreshold; +} + +//***************************************************************************** +// +//! @brief Set bits in the HOST side IOINTCTL register. +//! +//! This function may be used to set an interrupt bit to the host. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_host_int_set(uint32_t ui32Interrupt) +{ + // + // Set a bit that will cause an interrupt to the host. + // + AM_REG(IOSLAVE, IOINTCTL) = AM_REG_IOSLAVE_IOINTCTL_IOINTSET(ui32Interrupt); +} + +//***************************************************************************** +// +//! @brief Clear bits in the HOST side IOINTCTL register. +//! +//! This function may be used to clear an interrupt bit to the host. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_host_int_clear(uint32_t ui32Interrupt) +{ + // + // Clear bits that will cause an interrupt to the host. + // + AM_REG(IOSLAVE, IOINTCTL) = AM_REG_IOSLAVE_IOINTCTL_IOINTCLR(ui32Interrupt); +} + +//***************************************************************************** +// +//! @brief Get the bits in the HOST side IOINTCTL register. +//! +//! This function may be used to read the host side interrupt bits. +//! +//! @return None. +// +//***************************************************************************** +uint32_t +am_hal_ios_host_int_get(void) +{ + // + // return the value of the bits that will cause an interrupt to the host. + // + return AM_BFR(IOSLAVE, IOINTCTL, IOINT); +} + +//***************************************************************************** +// +//! @brief Get the enable bits in the HOST side IOINTCTL register. +//! +//! This function may be used to read the host side interrupt bits. +//! +//! @return None. +// +//***************************************************************************** +uint32_t +am_hal_ios_host_int_enable_get(void) +{ + // + // return the value of the bits that will cause an interrupt to the host. + // + return AM_BFR(IOSLAVE, IOINTCTL, IOINTEN); +} + +//***************************************************************************** +// +//! @brief Enable an IOS Access Interrupt. +//! +//! This function may be used to enable an interrupt to the NVIC. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_access_int_enable(uint32_t ui32Interrupt) +{ + // + // OR the desired interrupt into the enable register. + // + AM_REG(IOSLAVE, REGACCINTEN) |= ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Return all enabled IOS Access Interrupts. +//! +//! This function may be used to return all enabled IOS Access interrupts. +//! +//! @return the enabled interrrupts. +// +//***************************************************************************** +uint32_t +am_hal_ios_access_int_enable_get(void) +{ + // + // Return the enabled interrupts. + // + return AM_REG(IOSLAVE, REGACCINTEN); +} + +//***************************************************************************** +// +//! @brief Disable an IOS Access Interrupt. +//! +//! This function may be used to disable an interrupt to the NVIC. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_access_int_disable(uint32_t ui32Interrupt) +{ + // + // Clear the desired bit from the interrupt enable register. + // + AM_REG(IOSLAVE, REGACCINTEN) &= ~(ui32Interrupt); +} + +//***************************************************************************** +// +//! @brief Clear an IOS Access Interrupt. +//! +//! This function may be used to clear an interrupt to the NVIC. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_access_int_clear(uint32_t ui32Interrupt) +{ + // + // Use the interrupt clear register to deactivate the chosen interrupt. + // + AM_REG(IOSLAVE, REGACCINTCLR) = ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Set an IOS Access Interrupt. +//! +//! This function may be used to set an interrupt to the NVIC. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_access_int_set(uint32_t ui32Interrupt) +{ + // + // Use the interrupt set register to activate the chosen interrupt. + // + AM_REG(IOSLAVE, REGACCINTSET) = ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Check the status of an IOS Access Interrupt. +//! +//! @param bEnabledOnly - return only the enabled interrupt status. +//! +//! This function may be used to return the enabled interrupt status. +//! +//! @return the enabled interrupt status. +// +//***************************************************************************** +uint32_t +am_hal_ios_access_int_status_get(bool bEnabledOnly) +{ + if ( bEnabledOnly ) + { + uint32_t u32RetVal = AM_REG(IOSLAVE, REGACCINTSTAT); + return u32RetVal & AM_REG(IOSLAVE, REGACCINTEN); + + } + else + { + return AM_REG(IOSLAVE, REGACCINTSTAT); + } +} + +//***************************************************************************** +// +//! @brief Enable an IOS Interrupt. +//! +//! @param ui32Interrupt - desired interrupts. +//! +//! This function may be used to enable an interrupt to the NVIC. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_int_enable(uint32_t ui32Interrupt) +{ + // + // OR the desired interrupt into the enable register. + // + AM_REG(IOSLAVE, INTEN) |= ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Return all enabled IOS Interrupts. +//! +//! This function may be used to return all enabled IOS interrupts. +//! +//! @return the enabled interrrupts. +// +//***************************************************************************** +uint32_t +am_hal_ios_int_enable_get(void) +{ + // + // Return the enabled interrupts. + // + return AM_REG(IOSLAVE, INTEN); +} + +//***************************************************************************** +// +//! @brief Disable an IOS Interrupt. +//! +//! @param ui32Interrupt - desired interrupts. +//! +//! This function may be used to disable an interrupt to the NVIC. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_int_disable(uint32_t ui32Interrupt) +{ + // + // Clear the desired bit from the interrupt enable register. + // + AM_REG(IOSLAVE, INTEN) &= ~(ui32Interrupt); +} + +//***************************************************************************** +// +//! @brief Clear an IOS Interrupt. +//! +//! @param ui32Interrupt - desired interrupts. +//! +//! This function may be used to clear an interrupt to the NVIC. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_int_clear(uint32_t ui32Interrupt) +{ + // + // Use the interrupt clear register to deactivate the chosen interrupt. + // + AM_REG(IOSLAVE, INTCLR) = ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Set an IOS Interrupt. +//! +//! @param ui32Interrupt - desired interrupts. +//! +//! This function may be used to set an interrupt to the NVIC. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_int_set(uint32_t ui32Interrupt) +{ + // + // Use the interrupt clear register to deactivate the chosen interrupt. + // + AM_REG(IOSLAVE, INTSET) = ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Write to the LRAM. +//! +//! @param ui32Offset - offset into the LRAM to write. +//! @param ui8Value - value to be written. +//! +//! This function writes ui8Value to offset ui32Offset inside the LRAM. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_lram_write(uint32_t ui32Offset, uint8_t ui8Value) +{ + // + // Write the LRAM. + // + am_hal_ios_pui8LRAM[ui32Offset] = ui8Value; +} + +//***************************************************************************** +// +//! @brief Read from the LRAM. +//! +//! @param ui32Offset - offset into the LRAM to read. +//! +//! This function read from offset ui32Offset inside the LRAM. +//! +//! @return the value at ui32Offset. +// +//***************************************************************************** +uint8_t +am_hal_ios_lram_read(uint32_t ui32Offset) +{ + // + // Read the LRAM. + // + return am_hal_ios_pui8LRAM[ui32Offset]; +} + +//***************************************************************************** +// +//! @brief Check the status of an IOS Interrupt. +//! +//! @param bEnabledOnly - return only the enabled interrupt status. +//! +//! This function may be used to return the enabled interrupt status. +//! +//! @return the enabled interrupt status. +// +//***************************************************************************** +uint32_t +am_hal_ios_int_status_get(bool bEnabledOnly) +{ + if ( bEnabledOnly ) + { + uint32_t u32RetVal = AM_REG(IOSLAVE, INTSTAT); + return u32RetVal & AM_REG(IOSLAVE, INTEN); + + } + else + { + return AM_REG(IOSLAVE, INTSTAT); + } +} + +//***************************************************************************** +// +//! @brief Check the amount of space used in the FIFO +//! +//! This function returns the available data in the overall FIFO yet to be +//! read by the host. This takes into account the SRAM buffer and hardware FIFO +//! +//! @return Bytes used in the Overall FIFO. +// +//***************************************************************************** +uint32_t +am_hal_ios_fifo_space_used(void) +{ + uint32_t ui32Val; + uint32_t ui32Primask; + // + // Start a critical section for thread safety. + // + ui32Primask = am_hal_interrupt_master_disable(); + ui32Val = g_sSRAMBuffer.ui32Length; + ui32Val += AM_BFR(IOSLAVE, FIFOPTR, FIFOSIZ); + // + // End the critical section + // + am_hal_interrupt_master_set(ui32Primask); + return ui32Val; +} + + + +//***************************************************************************** +// +//! @brief Check the amount of space left in the FIFO +//! +//! This function returns the available space in the overall FIFO to accept +//! new data. This takes into account the SRAM buffer and hardware FIFO +//! +//! @return Bytes left in the Overall FIFO. +// +//***************************************************************************** +uint32_t +am_hal_ios_fifo_space_left(void) +{ + uint32_t ui32Val; + uint32_t ui32Primask; + // + // Start a critical section for thread safety. + // + ui32Primask = am_hal_interrupt_master_disable(); + // + // We waste one byte in HW FIFO + // + ui32Val = g_sSRAMBuffer.ui32Capacity + g_ui32HwFifoSize - 1; + ui32Val -= g_sSRAMBuffer.ui32Length; + ui32Val -= AM_BFR(IOSLAVE, FIFOPTR, FIFOSIZ); + // + // End the critical section + // + am_hal_interrupt_master_set(ui32Primask); + return ui32Val; +} + +//***************************************************************************** +// +//! @brief Check the amount of space left in the hardware FIFO +//! +//! This function reads the IOSLAVE FIFOPTR register and determines the amount +//! of space left in the IOS LRAM FIFO. +//! +//! @return Bytes left in the IOS FIFO. +// +//***************************************************************************** +static uint32_t +fifo_space_left(void) +{ + // + // We waste one byte in HW FIFO + // + return ((uint32_t)g_ui32HwFifoSize- AM_BFR(IOSLAVE, FIFOPTR, FIFOSIZ) - 1); +} + +//***************************************************************************** +// +// Helper function for managing IOS FIFO writes. +// +//***************************************************************************** +static void +fifo_write(uint8_t *pui8Data, uint32_t ui32NumBytes) +{ + uint8_t *pFifoPtr = g_pui8FIFOPtr; + uint8_t *pFifoBase = g_pui8FIFOBase; + uint8_t *pFifoEnd = g_pui8FIFOEnd; + while ( ui32NumBytes ) + { + // + // Write the data to the FIFO + // + *pFifoPtr++ = *pui8Data++; + ui32NumBytes--; + + // + // Make sure to wrap the FIFO pointer if necessary. + // + if ( pFifoPtr == pFifoEnd ) + { + pFifoPtr = pFifoBase; + } + } + g_pui8FIFOPtr = pFifoPtr; +} + +// +// Assembly code below assumes 8bit FIFOSIZ field aligned at a byte boundary +// +#if (((AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_M >> AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S) != 0xFF) \ + || (AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S & 0x3)) +#error "FIFOSIZ not 8bit value aligned at byte offset" +#endif + +// +// Byte offset of FIFOSIZ field in FIFOPTR register +// +#define BYTEOFFSET_FIFOSIZE (AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S >> 3) + +//***************************************************************************** +// +// Helper function in assembly for implementing the ReSync +// +//***************************************************************************** +#if defined(__GNUC_STDC_INLINE__) +#if (AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S != 8) +#error "AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S not 8" +#endif +__attribute__((naked)) +static void +internal_resync_fifoSize(uint32_t wrOffset, uint32_t maxFifoSize, uint32_t hwFifoPtrRegAddr) +{ + __asm + ( + " push {r3,r4}\n\t" // Save r3, r4 - used by this function + "__internal_resync_fifoSize_loop:\n\t" + " ldr r4, [r2]\n\t" // Load FIFOPTR register in r4 + " ubfx r3, r4, #8, #8\n\t" // Extract hwFifoSize to r3 + " uxtb r4, r4\n\t" // Extract rdOffset in r4 + " subs r4, r0, r4\n\t" // fifoSize in r4 = wrOffset - rdOffset + " it cc\n\t" // if (wrOffset < rdOffset) + " addcc r4, r4, r1\n\t" // fifoSize = maxFifoSize - (rdOffset - wrOffset) + " cmp r3, r4\n\t" // (hwFifoSize != fifoSize) + " beq __internal_resync_fifosize_done\n\t" + " strb r4, [r2, #1]\n\t" // Overwrite FIFOSIZ value with fifoSize + " b __internal_resync_fifoSize_loop\n\t" // Repeat the check + "__internal_resync_fifosize_done:\n\t" + " pop {r3,r4}\n\t" // Restore registers + " bx lr\n\t" + ); +} + +#elif defined(__ARMCC_VERSION) +__asm static void +internal_resync_fifoSize(uint32_t wrOffset, uint32_t maxFifoSize, uint32_t hwFifoPtrRegAddr) +{ + push {r3, r4} // Save r3, r4 - used by this function +internal_resync_fifoSize_loop + ldr r4, [r2] // Load FIFOPTR register in r4 + ubfx r3, r4, #AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S, #8 // Extract hwFifoSize to r3 + uxtb r4, r4 // Extract rdOffset in r4 + subs r4, r0, r4 // fifoSize in r4 = wrOffset - rdOffset + it cc // if (wrOffset < rdOffset), + addcc r4, r4, r1 // fifoSize = maxFifoSize - (rdOffset - wrOffset) + cmp r3, r4 // (hwFifoSize != fifoSize) + beq internal_resync_fifosize_done + strb r4, [r2, #1] // Overwrite FIFOSIZ value with fifoSize + b internal_resync_fifoSize_loop // Repeat the check +internal_resync_fifosize_done + pop {r3, r4} // Restore registers + bx lr +} + +#elif defined(__IAR_SYSTEMS_ICC__) +#if (AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S != 8) +#error "AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S not 8" +#endif +__stackless static void +internal_resync_fifoSize(uint32_t wrOffset, uint32_t maxFifoSize, uint32_t hwFifoPtrRegAddr) +{ + __asm volatile ( + " push {r3,r4}\n" // Save r3, r4 - used by this function + "__internal_resync_fifoSize_loop:\n" + " ldr r4, [r2]\n" // Load FIFOPTR register in r4 + " ubfx r3, r4, #8, #8\n" // Extract hwFifoSize to r3 + " uxtb r4, r4\n" // Extract rdOffset in r4 + " subs r4, r0, r4\n" // fifoSize in r4 = wrOffset - rdOffset + " it cc\n" + " addcc r4, r4, r1\n" // fifoSize = maxFifoSize - (rdOffset - wrOffset) + " cmp r3, r4\n" // (fifoSize != hwFifoSize) + " beq __internal_resync_fifosize_done\n" + " strb r4, [r2, #1]\n" // Overwrite FIFOSIZ value with fifoSize + " b __internal_resync_fifoSize_loop\n" // Repeat the check + "__internal_resync_fifosize_done:\n" + " pop {r3,r4}\n" // Restore registers + " bx lr\n" + ); +} + +#else +static void +internal_resync_fifoSize(uint32_t wrOffset, uint32_t maxFifoSize, uint32_t hwFifoPtrRegAddr) +{ + uint32_t fifoSize; + uint32_t hwFifoPtrReg; + uint32_t rdOffset; + uint32_t hwFifoSize; + + hwFifoPtrReg = AM_REGVAL(hwFifoPtrRegAddr); + rdOffset = ((hwFifoPtrReg & AM_REG_IOSLAVE_FIFOPTR_FIFOPTR_M) >> AM_REG_IOSLAVE_FIFOPTR_FIFOPTR_S); + hwFifoSize = (hwFifoPtrReg & AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_M) >> AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S; + // By wasting one byte in hardware FIFO, we're guaranteed that fifoSize does not need special handling for FULL FIFO case + fifoSize = ((wrOffset >= rdOffset) ? (wrOffset - rdOffset) : (maxFifoSize - (rdOffset - wrOffset))); + while ( fifoSize != hwFifoSize ) + { + // Overwite correct FIFOSIZ + // Need to do a Byte Write to make sure the FIFOPTR is not overwritten + *((uint8_t *)(hwFifoPtrRegAddr + BYTEOFFSET_FIFOSIZE)) = fifoSize; + // Read back the register and check for consistency + hwFifoPtrReg = AM_REGVAL(hwFifoPtrRegAddr); + rdOffset = ((hwFifoPtrReg & AM_REG_IOSLAVE_FIFOPTR_FIFOPTR_M) >> AM_REG_IOSLAVE_FIFOPTR_FIFOPTR_S); + hwFifoSize = (hwFifoPtrReg & AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_M) >> AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S; + // By wasting one byte in hardware FIFO, we're guaranteed that fifoSize does not need special handling for FULL FIFO case + fifoSize = ((wrOffset >= rdOffset) ? (wrOffset - rdOffset) : (hwFifoSize - (rdOffset - wrOffset))); + } +} +#endif + +// +// Address of the FIFOPTR register +// +#define AM_REG_IOS_FIFOPTR (REG_IOSLAVE_BASEADDR + AM_REG_IOSLAVE_FIFOPTR_O) + +// When the FIFO is being replenished by the SW, at the same time as host is +// reading from it, there is a possible race condition, where the hardware decrement +// of FIFOSIZ as a result of read gets overwritten by hardware increment due to +// write. +// This function re-sync's the FIFOSIZ to ensure such errors do not accumulate +void +resync_fifoSize(void) +{ + uint32_t ui32Primask; + uint32_t wrOffset = (uint32_t)g_pui8FIFOPtr - (uint32_t)am_hal_ios_pui8LRAM; + // + // Start a critical section for thread safety. + // + ui32Primask = am_hal_interrupt_master_disable(); + internal_resync_fifoSize(wrOffset, g_ui32HwFifoSize, AM_REG_IOS_FIFOPTR); + // Clear interrupts for IOS which could be spuriously triggered + AM_REG(IOSLAVE, REGACCINTCLR) = (AM_HAL_IOS_INT_FSIZE | AM_HAL_IOS_INT_FOVFL | AM_HAL_IOS_INT_FUNDFL); + // + // End the critical section + // + am_hal_interrupt_master_set(ui32Primask); + return; +} + +//***************************************************************************** +// +//! @brief Transfer any available data from the IOS SRAM buffer to the FIFO. +//! +//! This function is meant to be called from an interrupt handler for the +//! ioslave module. It checks the IOS FIFO interrupt status for a threshold +//! event, and transfers data from an SRAM buffer into the IOS FIFO. +//! +//! @param ui32Status should be set to the ios interrupt status at the time of +//! ISR entry. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_fifo_service(uint32_t ui32Status) +{ + uint32_t thresh; + uint32_t freeSpace, usedSpace, chunk1, chunk2, ui32WriteIndex; + + // + // Check for FIFO size interrupts. + // + if ( ui32Status & AM_HAL_IOS_INT_FSIZE ) + { + thresh = AM_BFR(IOSLAVE, FIFOTHR, FIFOTHR); + + // + // While the FIFO is at or below threshold Add more data + // If Fifo level is above threshold, we're guaranteed an FSIZ interrupt + // + while ( g_sSRAMBuffer.ui32Length && + ((usedSpace = AM_BFR(IOSLAVE, FIFOPTR, FIFOSIZ)) <= thresh) ) + { + // + // So, we do have some data in SRAM which needs to be moved to FIFO. + // A chunk of data is a continguous set of bytes in SRAM that can be + // written to FIFO. Determine the chunks of data from SRAM that can + // be written. Up to two chunks possible + // + ui32WriteIndex = g_sSRAMBuffer.ui32WriteIndex; + chunk1 = ((ui32WriteIndex > (uint32_t)g_sSRAMBuffer.ui32ReadIndex) ? \ + (ui32WriteIndex - (uint32_t)g_sSRAMBuffer.ui32ReadIndex) : \ + (g_sSRAMBuffer.ui32Capacity - (uint32_t)g_sSRAMBuffer.ui32ReadIndex)); + chunk2 = g_sSRAMBuffer.ui32Length - chunk1; + // We waste one byte in HW FIFO + freeSpace = g_ui32HwFifoSize - usedSpace - 1; + // Write data in chunks + // Determine the chunks of data from SRAM that can be written + if ( chunk1 > freeSpace ) + { + fifo_write((uint8_t *)(g_sSRAMBuffer.pui8Data + g_sSRAMBuffer.ui32ReadIndex), freeSpace); + // + // Advance the read index, wrapping if needed. + // + g_sSRAMBuffer.ui32ReadIndex += freeSpace; + // No need to check for wrap as we wrote less than chunk1 + // + // Adjust the length value to reflect the change. + // + g_sSRAMBuffer.ui32Length -= freeSpace; + } + else + { + fifo_write((uint8_t *)(g_sSRAMBuffer.pui8Data + g_sSRAMBuffer.ui32ReadIndex), chunk1); + + // + // Update the read index - wrapping as needed + // + g_sSRAMBuffer.ui32ReadIndex += chunk1; + g_sSRAMBuffer.ui32ReadIndex %= g_sSRAMBuffer.ui32Capacity; + // + // Adjust the length value to reflect the change. + // + g_sSRAMBuffer.ui32Length -= chunk1; + freeSpace -= chunk1; + + if ( freeSpace && chunk2 ) + { + if ( chunk2 > freeSpace ) + { + fifo_write((uint8_t *)(g_sSRAMBuffer.pui8Data + g_sSRAMBuffer.ui32ReadIndex), freeSpace); + + // + // Advance the read index, wrapping if needed. + // + g_sSRAMBuffer.ui32ReadIndex += freeSpace; + + // No need to check for wrap in chunk2 + // + // Adjust the length value to reflect the change. + // + g_sSRAMBuffer.ui32Length -= freeSpace; + } + else + { + fifo_write((uint8_t *)(g_sSRAMBuffer.pui8Data + g_sSRAMBuffer.ui32ReadIndex), chunk2); + // + // Advance the read index, wrapping if needed. + // + g_sSRAMBuffer.ui32ReadIndex += chunk2; + + // No need to check for wrap in chunk2 + // + // Adjust the length value to reflect the change. + // + g_sSRAMBuffer.ui32Length -= chunk2; + } + } + } + resync_fifoSize(); + + // + // Need to retake the FIFO space, after Threshold interrupt has been reenabled + // Clear any spurious FSIZE interrupt that might have got raised + // + AM_BFW(IOSLAVE, INTCLR, FSIZE, 1); + } + } +} + +//***************************************************************************** +// +//! @brief Writes the specified number of bytes to the IOS fifo. +//! +//! @param pui8Data is a pointer to the data to be written to the fifo. +//! @param ui32NumBytes is the number of bytes to send. +//! +//! This function will write data from the caller-provided array to the IOS +//! LRAM FIFO. If there is no space in the LRAM FIFO, the data will be copied +//! to a temporary SRAM buffer instead. +//! +//! The maximum message size for the IO Slave is 1023 bytes. +//! +//! @note In order for SRAM copy operations in the function to work correctly, +//! the \e am_hal_ios_buffer_service() function must be called in the ISR for +//! the ioslave module. +//! +//! @return Number of bytes written (could be less than ui32NumBytes, if not enough space) +// +//***************************************************************************** +uint32_t +am_hal_ios_fifo_write(uint8_t *pui8Data, uint32_t ui32NumBytes) +{ + uint32_t ui32FIFOSpace; + uint32_t ui32SRAMSpace; + uint32_t ui32SRAMLength; + uint32_t ui32Primask; + uint32_t totalBytes = ui32NumBytes; + + // + // This operation will only work properly if an SRAM buffer has been + // allocated. Make sure that am_hal_ios_fifo_buffer_init() has been called, + // and the buffer pointer looks valid. + // + am_hal_debug_assert(g_sSRAMBuffer.pui8Data != 0); + + if ( ui32NumBytes == 0 ) + { + return 0; + } + + // + // Start a critical section for thread safety. + // + ui32Primask = am_hal_interrupt_master_disable(); + + ui32SRAMLength = g_sSRAMBuffer.ui32Length; + // + // End the critical section + // + am_hal_interrupt_master_set(ui32Primask); + + // + // If the SRAM buffer is empty, we should just write directly to the FIFO. + // + if ( ui32SRAMLength == 0 ) + { + ui32FIFOSpace = fifo_space_left(); + + // + // If the whole message fits, send it now. + // + if ( ui32NumBytes <= ui32FIFOSpace ) + { + fifo_write(pui8Data, ui32NumBytes); + ui32NumBytes = 0; + } + else + { + fifo_write(pui8Data, ui32FIFOSpace); + ui32NumBytes -= ui32FIFOSpace; + pui8Data += ui32FIFOSpace; + }; + resync_fifoSize(); + } + + // + // If there's still data, write it to the SRAM buffer. + // + if ( ui32NumBytes ) + { + uint32_t idx, writeIdx, capacity, fifoSize; + ui32SRAMSpace = g_sSRAMBuffer.ui32Capacity - ui32SRAMLength; + + writeIdx = g_sSRAMBuffer.ui32WriteIndex; + capacity = g_sSRAMBuffer.ui32Capacity; + // + // Make sure that the data will fit inside the SRAM buffer. + // + if ( ui32SRAMSpace > ui32NumBytes ) + { + ui32SRAMSpace = ui32NumBytes; + } + + // + // If the data will fit, write it to the SRAM buffer. + // + for ( idx = 0; idx < ui32SRAMSpace; idx++ ) + { + g_sSRAMBuffer.pui8Data[(idx + writeIdx) % capacity] = pui8Data[idx]; + } + + ui32NumBytes -= idx; + // + // Start a critical section for thread safety before updating length & wrIdx. + // + ui32Primask = am_hal_interrupt_master_disable(); + // + // Advance the write index, making sure to wrap if necessary. + // + g_sSRAMBuffer.ui32WriteIndex = (idx + writeIdx) % capacity; + + // + // Update the length value appropriately. + // + g_sSRAMBuffer.ui32Length += idx; + // + // End the critical section + // + am_hal_interrupt_master_set(ui32Primask); + + // It is possible that there is a race condition that the FIFO level has + // gone below the threshold by the time we set the wrIdx above, and hence + // we may never get the threshold interrupt to serve the SRAM data we + // just wrote + + // If that is the case, explicitly generate the FSIZE interrupt from here + fifoSize = AM_BFR(IOSLAVE, FIFOPTR, FIFOSIZ); + if ( fifoSize <= AM_BFR(IOSLAVE, FIFOTHR, FIFOTHR) ) + { + AM_BFW(IOSLAVE, INTSET, FSIZE, 1); + } + } + + return (totalBytes - ui32NumBytes); +} + +//***************************************************************************** +// +//! @brief Writes the specified number of bytes to the IOS fifo simply. +//! +//! @param pui8Data is a pointer to the data to be written to the fifo. +//! @param ui32NumBytes is the number of bytes to send. +//! +//! This function will write data from the caller-provided array to the IOS +//! LRAM FIFO. This simple routine does not use SRAM buffering for large +//! messages. +//! +//! The maximum message size for the IO Slave is 128 bytes. +//! +//! @note Do note call the \e am_hal_ios_buffer_service() function in the ISR for +//! the ioslave module. +//! +//! @return +// +//***************************************************************************** +void +am_hal_ios_fifo_write_simple(uint8_t *pui8Data, uint32_t ui32NumBytes) +{ + uint32_t ui32FIFOSpace; + + // + // Check the FIFO and the SRAM buffer to see where we have space. + // + ui32FIFOSpace = fifo_space_left(); + + // + // If the whole message fits, send it now. + // + if ( ui32NumBytes <= ui32FIFOSpace ) + { + fifo_write(pui8Data, ui32NumBytes); + } + else + { + // + // The message didn't fit. Try using am_hal_ios_fifo_write() instead. + // + am_hal_debug_assert_msg(0, "The requested IOS transfer didn't fit in" + "the LRAM FIFO. Try using am_hal_ios_fifo_write()."); + } +} + +//***************************************************************************** +// +//! @brief Sets the IOS FIFO pointer to the specified LRAM offset. +//! +//! @param ui32Offset is LRAM offset to set the FIFO pointer to. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_fifo_ptr_set(uint32_t ui32Offset) +{ + uint32_t ui32Primask; + + // + // Start a critical section for thread safety. + // + ui32Primask = am_hal_interrupt_master_disable(); + + // + // Set the FIFO Update bit. + // + AM_REG(IOSLAVE, FUPD) = 0x1; + + // + // Change the FIFO offset. + // + AM_REG(IOSLAVE, FIFOPTR) = ui32Offset; + + // + // Clear the FIFO update bit. + // + AM_REG(IOSLAVE, FUPD) = 0x0; + + // + // Set the global FIFO-pointer tracking variable. + // + g_pui8FIFOPtr = (uint8_t *) (REG_IOSLAVE_BASEADDR + ui32Offset); + + // + // End the critical section. + // + am_hal_interrupt_master_set(ui32Primask); +} + +//***************************************************************************** +// +// Initialize an SRAM buffer for use with the IO Slave. +// +//***************************************************************************** +static void +am_hal_ios_buffer_init(am_hal_ios_buffer_t *psBuffer, void *pvArray, + uint32_t ui32Bytes) +{ + psBuffer->ui32WriteIndex = 0; + psBuffer->ui32ReadIndex = 0; + psBuffer->ui32Length = 0; + psBuffer->ui32Capacity = ui32Bytes; + psBuffer->pui8Data = (uint8_t *)pvArray; +} + +//***************************************************************************** +// +//! @brief Poll for all host side read activity to complete. +//! +//! Poll for all host side read activity to complete. Use this before +//! calling am_hal_ios_fifo_write_simple(). +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_read_poll_complete(void) +{ + while ( AM_REG(IOSLAVE, FUPD) & AM_REG_IOSLAVE_FUPD_IOREAD_M ); +} + +//***************************************************************************** +// +//! @brief Initializes an SRAM buffer for the IOS FIFO. +//! +//! @param pui8Buffer is the SRAM buffer that will be used for IOS fifo data. +//! @param ui32BufferSize is the size of the SRAM buffer. +//! +//! This function provides the IOS HAL functions with working memory for +//! managing outgoing IOS FIFO transactions. It needs to be called at least +//! once before am_hal_ios_fifo_write() may be used. +//! +//! The recommended buffer size for the IOS FIFO is 1024 bytes. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_fifo_buffer_init(uint8_t *pui8Buffer, uint32_t ui32NumBytes) +{ + // + // Initialize the global SRAM buffer + // Total size, which is SRAM Buffer plus the hardware FIFO needs to be + // limited to 1023 + // + if ( ui32NumBytes > (1023 - g_ui32HwFifoSize + 1) ) + { + ui32NumBytes = (1023 - g_ui32HwFifoSize + 1); + } + + am_hal_ios_buffer_init(&g_sSRAMBuffer, pui8Buffer, ui32NumBytes); + + // + // Clear the FIFO State + // + AM_BFW(IOSLAVE, FIFOCTR, FIFOCTR, 0x0); + AM_BFW(IOSLAVE, FIFOPTR, FIFOSIZ, 0x0); + + am_hal_ios_fifo_ptr_set(g_ui32FifoBaseOffset); +} + +//***************************************************************************** +// +//! @brief Update the FIFOCTR to inform host of available data to read. +//! +//! This function allows the application to indicate to HAL when it is safe to +//! update the FIFOCTR. +//! +//! Application needs to implement some sort of +//! synchronization with the host to make sure host is not reading FIFOCTR while +//! it is being updated by the MCU, since the FIFOCTR read over +//! IO is not an atomic operation. +//! +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_ios_update_fifoctr(void) +{ + uint32_t ui32Val; + // Determine the available data + ui32Val = am_hal_ios_fifo_space_used(); + // Update FIFOCTR + AM_BFW(IOSLAVE, FIFOCTR, FIFOCTR, ui32Val); + return; +} + +//***************************************************************************** +// +// End the doxygen group +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_ios.h b/bsp/apollo2/libraries/drivers/hal/am_hal_ios.h new file mode 100644 index 0000000000..b166c9c6e5 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_ios.h @@ -0,0 +1,362 @@ +//***************************************************************************** +// +// am_hal_ios.h +//! @file +//! +//! @brief Functions for interfacing with the IO Slave module +//! +//! @addtogroup ios2 IO Slave (SPI/I2C) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_IOS_H +#define AM_HAL_IOS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +//! @name Interface Configuration +//! @brief Macro definitions for configuring the physical interface of the IO +//! Slave +//! +//! These macros may be used with the am_hal_ios_config_t structure to set the +//! physical parameters of the SPI/I2C slave module. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_IOS_USE_SPI AM_REG_IOSLAVE_CFG_IFCSEL_SPI +#define AM_HAL_IOS_SPIMODE_0 AM_REG_IOSLAVE_CFG_SPOL_SPI_MODES_0_3 +#define AM_HAL_IOS_SPIMODE_1 AM_REG_IOSLAVE_CFG_SPOL_SPI_MODES_1_2 +#define AM_HAL_IOS_SPIMODE_2 AM_REG_IOSLAVE_CFG_SPOL_SPI_MODES_1_2 +#define AM_HAL_IOS_SPIMODE_3 AM_REG_IOSLAVE_CFG_SPOL_SPI_MODES_0_3 + +#define AM_HAL_IOS_USE_I2C AM_REG_IOSLAVE_CFG_IFCSEL_I2C +#define AM_HAL_IOS_I2C_ADDRESS(n) AM_REG_IOSLAVE_CFG_I2CADDR(n) + +#define AM_HAL_IOS_LSB_FIRST AM_REG_IOSLAVE_CFG_LSB(1) +//! @} + +//***************************************************************************** +// +//! @name Register Access Interrupts +//! @brief Macro definitions for register access interrupts. +//! +//! These macros may be used with any of the +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_IOS_ACCESS_INT_00 AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 31) +#define AM_HAL_IOS_ACCESS_INT_01 AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 30) +#define AM_HAL_IOS_ACCESS_INT_02 AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 29) +#define AM_HAL_IOS_ACCESS_INT_03 AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 28) +#define AM_HAL_IOS_ACCESS_INT_04 AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 27) +#define AM_HAL_IOS_ACCESS_INT_05 AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 26) +#define AM_HAL_IOS_ACCESS_INT_06 AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 25) +#define AM_HAL_IOS_ACCESS_INT_07 AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 24) +#define AM_HAL_IOS_ACCESS_INT_08 AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 23) +#define AM_HAL_IOS_ACCESS_INT_09 AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 22) +#define AM_HAL_IOS_ACCESS_INT_0A AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 21) +#define AM_HAL_IOS_ACCESS_INT_0B AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 20) +#define AM_HAL_IOS_ACCESS_INT_0C AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 19) +#define AM_HAL_IOS_ACCESS_INT_0D AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 18) +#define AM_HAL_IOS_ACCESS_INT_0E AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 17) +#define AM_HAL_IOS_ACCESS_INT_0F AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 16) +#define AM_HAL_IOS_ACCESS_INT_13 AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 15) +#define AM_HAL_IOS_ACCESS_INT_17 AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 14) +#define AM_HAL_IOS_ACCESS_INT_1B AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 13) +#define AM_HAL_IOS_ACCESS_INT_1F AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 12) +#define AM_HAL_IOS_ACCESS_INT_23 AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 11) +#define AM_HAL_IOS_ACCESS_INT_27 AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 10) +#define AM_HAL_IOS_ACCESS_INT_2B AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 9) +#define AM_HAL_IOS_ACCESS_INT_2F AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 8) +#define AM_HAL_IOS_ACCESS_INT_33 AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 7) +#define AM_HAL_IOS_ACCESS_INT_37 AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 6) +#define AM_HAL_IOS_ACCESS_INT_3B AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 5) +#define AM_HAL_IOS_ACCESS_INT_3F AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 4) +#define AM_HAL_IOS_ACCESS_INT_43 AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 3) +#define AM_HAL_IOS_ACCESS_INT_47 AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 2) +#define AM_HAL_IOS_ACCESS_INT_4B AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 1) +#define AM_HAL_IOS_ACCESS_INT_4F AM_REG_IOSLAVE_REGACCINTEN_REGACC((uint32_t)1 << 0) +#define AM_HAL_IOS_ACCESS_INT_ALL 0xFFFFFFFF +//! @} + +//***************************************************************************** +// +//! @name I/O Slave Interrupts +//! @brief Macro definitions for I/O slave (IOS) interrupts. +//! +//! These macros may be used with any of the +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_IOS_INT_FSIZE AM_REG_IOSLAVE_INTEN_FSIZE_M +#define AM_HAL_IOS_INT_FOVFL AM_REG_IOSLAVE_INTEN_FOVFL_M +#define AM_HAL_IOS_INT_FUNDFL AM_REG_IOSLAVE_INTEN_FUNDFL_M +#define AM_HAL_IOS_INT_FRDERR AM_REG_IOSLAVE_INTEN_FRDERR_M +#define AM_HAL_IOS_INT_GENAD AM_REG_IOSLAVE_INTEN_GENAD_M +#define AM_HAL_IOS_INT_IOINTW AM_REG_IOSLAVE_INTEN_IOINTW_M +#define AM_HAL_IOS_INT_XCMPWR AM_REG_IOSLAVE_INTEN_XCMPWR_M +#define AM_HAL_IOS_INT_XCMPWF AM_REG_IOSLAVE_INTEN_XCMPWF_M +#define AM_HAL_IOS_INT_XCMPRR AM_REG_IOSLAVE_INTEN_XCMPRR_M +#define AM_HAL_IOS_INT_XCMPRF AM_REG_IOSLAVE_INTEN_XCMPRF_M +#define AM_HAL_IOS_INT_ALL 0xFFFFFFFF +//! @} + +//***************************************************************************** +// +//! @name I/O Slave Interrupts triggers +//! @brief Macro definitions for I/O slave (IOS) interrupts. +//! +//! These macros may be used with am_hal_ios_int_set and am_hal_ios_int_clear +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_IOS_IOINTCTL_INT0 (0x01) +#define AM_HAL_IOS_IOINTCTL_INT1 (0x02) +#define AM_HAL_IOS_IOINTCTL_INT2 (0x04) +#define AM_HAL_IOS_IOINTCTL_INT3 (0x08) +#define AM_HAL_IOS_IOINTCTL_INT4 (0x10) +#define AM_HAL_IOS_IOINTCTL_INT5 (0x20) +//! @} + +//***************************************************************************** +// +// External variable definitions +// +//***************************************************************************** + +//***************************************************************************** +// +//! @brief LRAM pointer +//! +//! Pointer to the base of the IO Slave LRAM. +// +//***************************************************************************** +extern volatile uint8_t * const am_hal_ios_pui8LRAM; + +//***************************************************************************** +// +//! @brief Configuration structure for the IO slave module. +//! +//! This structure may be used along with the am_hal_ios_config() function to +//! select key parameters of the IO Slave module. See the descriptions of each +//! parameter within this structure for more information on what they control. +// +//***************************************************************************** +typedef struct +{ + // + //! Interface Selection + //! + //! This word selects the physical behavior of the IO Slave port. For SPI + //! mode, this word should be the logical OR of one or more of the + //! following: + //! + //! AM_HAL_IOS_USE_SPI + //! AM_HAL_IOS_SPIMODE_0 + //! AM_HAL_IOS_SPIMODE_1 + //! AM_HAL_IOS_SPIMODE_2 + //! AM_HAL_IOS_SPIMODE_3 + //! + //! For I2C mode, use the logical OR of one or more of these values instead + //! (where n is the 7 or 10-bit I2C address to use): + //! + //! AM_HAL_IOS_USE_I2C + //! AM_HAL_IOS_I2C_ADDRESS(n) + //! + //! Also, in any mode, you may OR in this value to reverse the order of + //! incoming data bits. + //! + //! AM_HAL_IOS_LSB_FIRST + // + uint32_t ui32InterfaceSelect; + + // + //! Read-Only section + //! + //! The IO Slave LRAM is split into three main sections. The first section + //! is a "Direct Write" section, which may be accessed for reads or write + //! either directly through the Apollo CPU, or over the SPI/I2C bus. The + //! "Direct Write" section always begins at LRAM offset 0x0. At the end of + //! the normal "Direct Write" space, there is a "Read Only" space, which is + //! read/write accessible to the Apollo CPU, but read-only over the I2C/SPI + //! Bus. This word selects the base address of this "Read Only" space. + //! + //! This value may be set to any multiple of 8 between 0x0 and 0x78, + //! inclusive. For the configuration to be valid, \e ui32ROBase must also + //! be less than or equal to \e ui32FIFOBase + //! + //! @note The address given here is in units of BYTES. Since the location + //! of the "Read Only" space may only be set in 8-byte increments, this + //! value must be a multiple of 8. + //! + //! For the avoidance of doubt this means 0x80 is 128 bytes. These functions + //! will shift right by 8 internally. + // + uint32_t ui32ROBase; + + // + //! FIFO section + //! + //! After the "Direct Access" and "Read Only" sections is a section of LRAM + //! allocated to a FIFO. This section is accessible by the Apollo CPU + //! through the FIFO control registers, and accessible on the SPI/I2C bus + //! through the 0x7F address. This word selects the base address of the + //! FIFO space. The FIFO will extend from the address specified here to the + //! address specified in \e ui32RAMBase. + //! + //! This value may be set to any multiple of 8 between 0x0 and 0x78, + //! inclusive. For the configuration to be valid, \e ui32FIFOBase must also + //! be greater than or equal to \e ui32ROBase. + //! + //! @note The address given here is in units of BYTES. Since the location + //! of the "FIFO" space may only be set in 8-byte increments, this value + //! must be a multiple of 8. + //! + //! For the avoidance of doubt this means 0x80 is 128 bytes. These functions + //! will shift right by 8 internally. + // + uint32_t ui32FIFOBase; + + // + //! RAM section + //! + //! At the end of the IOS LRAM, the user may allocate a "RAM" space that + //! can only be accessed by the Apollo CPU. This space will not interact + //! with the SPI/I2C bus at all, and may be used as general-purpose memory. + //! Unlike normal SRAM, this section of LRAM will retain its state through + //! Deep Sleep, so it may be used as a data retention space for + //! ultra-low-power applications. + //! + //! This value may be set to any multiple of 8 between 0x0 and 0x100, + //! inclusive. For the configuration to be valid, \e ui32RAMBase must also + //! be greater than or equal to \e ui32FIFOBase. + //! + //! @note The address given here is in units of BYTES. Since the location + //! of the "FIFO" space may only be set in 8-byte increments, this value + //! must be a multiple of 8. + //! + //! For the avoidance of doubt this means 0x80 is 128 bytes. These functions + //! will shift right by 8 internally. + // + uint32_t ui32RAMBase; + + // + //! FIFO threshold + //! + //! The IO Slave module will trigger an interrupt when the number of + //! entries in the FIFO drops below this number of bytes. + // + uint32_t ui32FIFOThreshold; + + // + // Pointer to an SRAM + // + uint8_t *pui8SRAMBuffer; +} +am_hal_ios_config_t; + +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern void am_hal_ios_enable(uint32_t ui32Module); +extern void am_hal_ios_disable(uint32_t ui32Module); + +// these interrupts drive the HOST side IOS interrupt pins +extern void am_hal_ios_host_int_set(uint32_t ui32Interrupt); +extern void am_hal_ios_host_int_clear(uint32_t ui32Interrupt); +extern uint32_t am_hal_ios_host_int_get(void); +extern uint32_t am_hal_ios_host_int_enable_get(void); + +extern void am_hal_ios_lram_write(uint32_t ui32Offset, uint8_t ui8Value); +extern uint8_t am_hal_ios_lram_read(uint32_t ui32Offset); + +// the following interrupts go back to the NVIC +extern void am_hal_ios_config(am_hal_ios_config_t *psConfig); +extern void am_hal_ios_access_int_enable(uint32_t ui32Interrupt); +extern uint32_t am_hal_ios_access_int_enable_get(void); +extern void am_hal_ios_access_int_disable(uint32_t ui32Interrupt); +extern void am_hal_ios_access_int_clear(uint32_t ui32Interrupt); +extern void am_hal_ios_access_int_set(uint32_t ui32Interrupt); +extern uint32_t am_hal_ios_access_int_status_get(bool bEnabledOnly); +extern void am_hal_ios_int_enable(uint32_t ui32Interrupt); +extern uint32_t am_hal_ios_int_enable_get(void); +extern void am_hal_ios_int_disable(uint32_t ui32Interrupt); +extern void am_hal_ios_int_clear(uint32_t ui32Interrupt); +extern void am_hal_ios_int_set(uint32_t ui32Interrupt); +extern uint32_t am_hal_ios_int_status_get(bool bEnabledOnly); + +extern void am_hal_ios_fifo_buffer_init(uint8_t *pui8Buffer, uint32_t ui32NumBytes); +extern uint32_t am_hal_ios_fifo_space_left(void); +extern uint32_t am_hal_ios_fifo_space_used(void); +extern void am_hal_ios_fifo_service(uint32_t ui32Status); +// Returns the number of bytes actually written +extern uint32_t am_hal_ios_fifo_write(uint8_t *pui8Data, uint32_t ui32NumBytes); +extern void am_hal_ios_fifo_write_simple(uint8_t *pui8Data, + uint32_t ui32NumBytes); +extern void am_hal_ios_fifo_ptr_set(uint32_t ui32Offset); +extern void am_hal_ios_update_fifoctr(void); + +extern void am_hal_ios_read_poll_complete(void); +extern void am_hal_ios_pwrctrl_enable(void); +extern void am_hal_ios_pwrctrl_disable(void); + + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_IOS_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_itm.c b/bsp/apollo2/libraries/drivers/hal/am_hal_itm.c new file mode 100644 index 0000000000..0f57c0d417 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_itm.c @@ -0,0 +1,453 @@ +//***************************************************************************** +// +// am_hal_itm.c +//! @file +//! +//! @brief Functions for operating the instrumentation trace macrocell +//! +//! @addtogroup itm2 Instrumentation Trace Macrocell (ITM) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +// Global Variables +// +//***************************************************************************** + +//***************************************************************************** +// +//! @brief Delays for a desired amount of microseconds. +//! +//! @note - This function is based on the similar function in am_util_delay.c, +//! please see that module for implementation details. It was necessary to +//! duplicate it here to avoid having to update every example to include the +//! am_util_delay.c module in its build. +//! +//! @returns None +// +//***************************************************************************** +void +am_hal_itm_delay_us(uint32_t ui32MicroSeconds) +{ + uint32_t ui32Iterations = ui32MicroSeconds * + (am_hal_clkgen_sysclk_get() / 3000000); + + // + // Call the BOOTROM cycle delay function + // + am_hal_flash_delay(ui32Iterations); +} + +//***************************************************************************** +// +//! @brief Enables the ITM +//! +//! This function enables the ARM ITM by setting the TRCENA bit in the DEMCR +//! register. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_itm_enable(void) +{ + if (g_ui32HALflags & AM_HAL_FLAGS_ITMSKIPENABLEDISABLE_M) + { + return; + } + + // + // To be able to access ITM registers, set the Trace Enable bit + // in the Debug Exception and Monitor Control Register (DEMCR). + // + AM_REG(SYSCTRL, DEMCR) |= AM_REG_SYSCTRL_DEMCR_TRCENA(1); + while ( !(AM_REG(SYSCTRL, DEMCR) & AM_REG_SYSCTRL_DEMCR_TRCENA(1)) ); + + // + // Write the key to the ITM Lock Access register to unlock the ITM_TCR. + // + AM_REGVAL(AM_REG_ITM_LOCKAREG_O) = AM_REG_ITM_LOCKAREG_KEYVAL; + + // + // Set the enable bits in the ITM trace enable register, and the ITM + // control registers to enable trace data output. + // + AM_REGVAL(AM_REG_ITM_TPR_O) = 0x0000000f; + AM_REGVAL(AM_REG_ITM_TER_O) = 0xffffffff; + + // + // Write to the ITM control and status register (don't enable yet). + // + AM_REGVAL(AM_REG_ITM_TCR_O) = + AM_WRITE_SM(AM_REG_ITM_TCR_ATB_ID, 0x15) | + AM_WRITE_SM(AM_REG_ITM_TCR_TS_FREQ, 1) | + AM_WRITE_SM(AM_REG_ITM_TCR_TS_PRESCALE, 1) | + AM_WRITE_SM(AM_REG_ITM_TCR_SWV_ENABLE, 1) | + AM_WRITE_SM(AM_REG_ITM_TCR_DWT_ENABLE, 0) | + AM_WRITE_SM(AM_REG_ITM_TCR_SYNC_ENABLE, 0) | + AM_WRITE_SM(AM_REG_ITM_TCR_TS_ENABLE, 0) | + AM_WRITE_SM(AM_REG_ITM_TCR_ITM_ENABLE, 1); +} + +//***************************************************************************** +// +//! @brief Disables the ITM +//! +//! This function completely disables the ARM ITM by resetting the TRCENA bit +//! in the DEMCR register. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_itm_disable(void) +{ + + if (g_ui32HALflags & AM_HAL_FLAGS_ITMSKIPENABLEDISABLE_M) + { + return; + } + + // + // Make sure the ITM_TCR is unlocked. + // + AM_REGVAL(AM_REG_ITM_LOCKAREG_O) = AM_REG_ITM_LOCKAREG_KEYVAL; + + // + // Make sure the ITM/TPIU is not busy. + // + while ( AM_REG(ITM, TCR) & AM_REG_ITM_TCR_BUSY(1) ); + + // + // Disable the ITM. + // + for (int ix = 0; ix < 100; ix++) + { + AM_REG(ITM, TCR) &= ~AM_REG_ITM_TCR_ITM_ENABLE(1); + while ( AM_REG(ITM, TCR) & (AM_REG_ITM_TCR_ITM_ENABLE(1) | AM_REG_ITM_TCR_BUSY(1)) ); + } + + // + // Reset the TRCENA bit in the DEMCR register, which should disable the ITM + // for operation. + // + AM_REG(SYSCTRL, DEMCR) &= ~AM_REG_SYSCTRL_DEMCR_TRCENA(1); + + // + // Disable the TPIU clock source in MCU control. + // + AM_REG(MCUCTRL, TPIUCTRL) = AM_REG_MCUCTRL_TPIUCTRL_CLKSEL_0MHz | + AM_REG_MCUCTRL_TPIUCTRL_ENABLE_DIS; +} + +//***************************************************************************** +// +//! @brief Checks if itm is busy and provides a delay to flush the fifo +//! +//! This function disables the ARM ITM by resetting the TRCENA bit in the DEMCR +//! register. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_itm_not_busy(void) +{ + // + // Make sure the ITM/TPIU is not busy. + // + while (AM_REG(ITM, TCR) & AM_REG_ITM_TCR_BUSY(1)); + + // + // wait for 50us for the data to flush out + // + am_hal_itm_delay_us(50); +} + +//***************************************************************************** +// +//! @brief Enables tracing on a given set of ITM ports +//! +//! @param ui8portNum - Set ports to be enabled +//! +//! Enables tracing on the ports referred to by \e ui8portNum by writing the +//! associated bit in the Trace Privilege Register in the ITM. The value for +//! ui8portNum should be the logical OR one or more of the following values: +//! +//! \e ITM_PRIVMASK_0_7 - enable ports 0 through 7 +//! \e ITM_PRIVMASK_8_15 - enable ports 8 through 15 +//! \e ITM_PRIVMASK_16_23 - enable ports 16 through 23 +//! \e ITM_PRIVMASK_24_31 - enable ports 24 through 31 +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_itm_trace_port_enable(uint8_t ui8portNum) +{ + AM_REGVAL(AM_REG_ITM_TPR_O) |= (0x00000001 << (ui8portNum>>3)); +} + +//***************************************************************************** +// +//! @brief Disable tracing on the given ITM stimulus port. +//! +//! @param ui8portNum +//! +//! Disables tracing on the ports referred to by \e ui8portNum by writing the +//! associated bit in the Trace Privilege Register in the ITM. The value for +//! ui8portNum should be the logical OR one or more of the following values: +//! +//! \e ITM_PRIVMASK_0_7 - disable ports 0 through 7 +//! \e ITM_PRIVMASK_8_15 - disable ports 8 through 15 +//! \e ITM_PRIVMASK_16_23 - disable ports 16 through 23 +//! \e ITM_PRIVMASK_24_31 - disable ports 24 through 31 +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_itm_trace_port_disable(uint8_t ui8portNum) +{ + AM_REGVAL(AM_REG_ITM_TPR_O) &= ~(0x00000001 << (ui8portNum >> 3)); +} + +//***************************************************************************** +// +//! @brief Poll the given ITM stimulus register until not busy. +//! +//! @param ui32StimReg - stimulus register +//! +//! @return true if not busy, false if busy (timed out or other error). +// +//***************************************************************************** +bool +am_hal_itm_stimulus_not_busy(uint32_t ui32StimReg) +{ + uint32_t ui32StimAddr = (AM_REG_ITM_STIM0_O + (4 * ui32StimReg)); + + // + // Busy waiting until it is available, non-zero means ready. + // + while (!AM_REGVAL(ui32StimAddr)); + + return true; +} + +//***************************************************************************** +// +//! @brief Writes a 32-bit value to the given ITM stimulus register. +//! +//! @param ui32StimReg - stimulus register +//! @param ui32Value - value to be written. +//! +//! Write a word to the desired stimulus register. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_itm_stimulus_reg_word_write(uint32_t ui32StimReg, uint32_t ui32Value) +{ + uint32_t ui32StimAddr; + + ui32StimAddr = (AM_REG_ITM_STIM0_O + (4 * ui32StimReg)); + + // + // Busy waiting until it is available, non-zero means ready + // + while (!AM_REGVAL(ui32StimAddr)); + + // + // Write the register. + // + AM_REGVAL(ui32StimAddr) = ui32Value; +} + +//***************************************************************************** +// +//! @brief Writes a short to the given ITM stimulus register. +//! +//! @param ui32StimReg - stimulus register +//! @param ui16Value - short to be written. +//! +//! Write a short to the desired stimulus register. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_itm_stimulus_reg_short_write(uint32_t ui32StimReg, uint16_t ui16Value) +{ + uint32_t ui32StimAddr; + + ui32StimAddr = (AM_REG_ITM_STIM0_O + (4 * ui32StimReg)); + + // + // Busy waiting until it is available non-zero means ready + // + while (!AM_REGVAL(ui32StimAddr)); + + // + // Write the register. + // + *((volatile uint16_t *) ui32StimAddr) = ui16Value; +} + +//***************************************************************************** +// +//! @brief Writes a byte to the given ITM stimulus register. +//! +//! @param ui32StimReg - stimulus register +//! @param ui8Value - byte to be written. +//! +//! Write a byte to the desired stimulus register. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_itm_stimulus_reg_byte_write(uint32_t ui32StimReg, uint8_t ui8Value) +{ + uint32_t ui32StimAddr; + + ui32StimAddr = (AM_REG_ITM_STIM0_O + (4 * ui32StimReg)); + + // + // Busy waiting until it is available (non-zero means ready) + // + while (!AM_REGVAL(ui32StimAddr)); + + // + // Write the register. + // + *((volatile uint8_t *) ui32StimAddr) = ui8Value; +} + +//***************************************************************************** +// +//! @brief Sends a Sync Packet. +//! +//! Sends a sync packet. This can be useful for external software should it +//! become out of sync with the ITM stream. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_itm_sync_send(void) +{ + // + // Write the register. + // + am_hal_itm_stimulus_reg_word_write(AM_HAL_ITM_SYNC_REG, + AM_HAL_ITM_SYNC_VAL); +} + +//***************************************************************************** +// +//! @brief Poll the print stimulus registers until not busy. +//! +//! @return true if not busy, false if busy (timed out or other error). +// +//***************************************************************************** +bool +am_hal_itm_print_not_busy(void) +{ + // + // Poll stimulus register allocated for printing. + // + am_hal_itm_stimulus_not_busy(0); + + + return true; +} + +//***************************************************************************** +// +//! @brief Prints a char string out of the ITM. +//! +//! @param pcString pointer to the character sting +//! +//! This function prints a sting out of the ITM. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_itm_print(char *pcString) +{ + uint32_t ui32Length = 0; + + // + // Determine the length of the string. + // + while (*(pcString + ui32Length)) + { + ui32Length++; + } + + // + // If there is no longer a word left, empty out the remaining characters. + // + while (ui32Length) + { + // + // Print string out the ITM. + // + am_hal_itm_stimulus_reg_byte_write(0, (uint8_t)*pcString++); + + // + // Subtract from length. + // + ui32Length--; + } +} +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_itm.h b/bsp/apollo2/libraries/drivers/hal/am_hal_itm.h new file mode 100644 index 0000000000..e747b0ab65 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_itm.h @@ -0,0 +1,107 @@ +//***************************************************************************** +// +// am_hal_itm.h +//! @file +//! +//! @brief Functions for accessing and configuring the ARM ITM. +//! +//! @addtogroup itm2 Instrumentation Trace Macrocell (ITM) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#ifndef AM_HAL_ITM_H +#define AM_HAL_ITM_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Sync Packet Defines +// +//***************************************************************************** +#define AM_HAL_ITM_SYNC_REG 23 +#define AM_HAL_ITM_SYNC_VAL 0xF8F8F8F8 + +//***************************************************************************** +// +// PrintF Setup +// +//***************************************************************************** +#define AM_HAL_ITM_PRINT_NUM_BYTES 1 +#define AM_HAL_ITM_PRINT_NUM_REGS 1 +extern uint32_t am_hal_itm_print_registers[AM_HAL_ITM_PRINT_NUM_REGS]; + +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern void am_hal_itm_delay_us(uint32_t ui32MicroSeconds); +extern void am_hal_itm_enable(void); +extern void am_hal_itm_disable(void); +extern void am_hal_itm_not_busy(void); +extern void am_hal_itm_sync_send(void); +extern void am_hal_itm_trace_port_enable(uint8_t ui8portNum); +extern void am_hal_itm_trace_port_disable(uint8_t ui8portNum); +extern bool am_hal_itm_stimulus_not_busy(uint32_t ui32StimReg); +extern void am_hal_itm_stimulus_reg_word_write(uint32_t ui32StimReg, + uint32_t ui32Value); +extern void am_hal_itm_stimulus_reg_short_write(uint32_t ui32StimReg, + uint16_t ui16Value); +extern void am_hal_itm_stimulus_reg_byte_write(uint32_t ui32StimReg, + uint8_t ui8Value); +extern bool am_hal_itm_print_not_busy(void); +extern void am_hal_itm_print(char *pcString); + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_ITM_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_mcuctrl.c b/bsp/apollo2/libraries/drivers/hal/am_hal_mcuctrl.c new file mode 100644 index 0000000000..f7b60e3c1a --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_mcuctrl.c @@ -0,0 +1,292 @@ +//***************************************************************************** +// +// am_hal_mcuctrl.c +//! @file +//! +//! @brief Functions for interfacing with the MCUCTRL. +//! +//! @addtogroup mcuctrl2 MCU Control (MCUCTRL) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +#define LDO_TRIM_REG_ADDR (0x50023004) +#define BUCK_TRIM_REG_ADDR (0x50023000) + +//***************************************************************************** +// +// Global Variables. +// +//***************************************************************************** +// +// Define the flash sizes from CHIP_INFO. +// +const uint32_t g_am_hal_mcuctrl_flash_size[16] = +{ + 16 * 1024, /* 0x0 0x00004000 16 KB */ + 32 * 1024, /* 0x1 0x00008000 32 KB */ + 64 * 1024, /* 0x2 0x00010000 64 KB */ + 128 * 1024, /* 0x3 0x00020000 128 KB */ + 256 * 1024, /* 0x4 0x00040000 256 KB */ + 512 * 1024, /* 0x5 0x00080000 512 KB */ + 1 * 1024 * 1024, /* 0x6 0x00100000 1 MB */ + 2 * 1024 * 1024, /* 0x7 0x00200000 2 MB */ + 4 * 1024 * 1024, /* 0x8 0x00400000 4 MB */ + 8 * 1024 * 1024, /* 0x9 0x00800000 8 MB */ + 16 * 1024 * 1024, /* 0xA 0x01000000 16 MB */ + 32 * 1024 * 1024, /* 0xB 0x02000000 32 MB */ + 64 * 1024 * 1024, /* 0xC 0x04000000 64 MB */ + 128 * 1024 * 1024, /* 0xD 0x08000000 128 MB */ + 256 * 1024 * 1024, /* 0xE 0x10000000 256 MB */ + 512 * 1024 * 1024 /* 0xF 0x20000000 512 MB */ +}; + +// +// Define the SRAM sizes from CHIP_INFO. +// For Apollo2, the SRAM sizes are defined exactly the same as the flash sizes. +// +#define g_am_hal_mcuctrl_sram_size g_am_hal_mcuctrl_flash_size + +//***************************************************************************** +// +//! @brief Gets all relevant device information. +//! +//! @param psDevice is a pointer to a structure that will be used to store all +//! device info. +//! +//! This function gets the device part number, chip IDs, and revision and +//! stores them in the passed structure. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_mcuctrl_device_info_get(am_hal_mcuctrl_device_t *psDevice) +{ + // + // Read the Part Number. + // + psDevice->ui32ChipPN = AM_REG(MCUCTRL, CHIP_INFO); + + // + // Read the Chip ID0. + // + psDevice->ui32ChipID0 = AM_REG(MCUCTRL, CHIPID0); + + // + // Read the Chip ID1. + // + psDevice->ui32ChipID1 = AM_REG(MCUCTRL, CHIPID1); + + // + // Read the Chip Revision. + // + psDevice->ui32ChipRev = AM_REG(MCUCTRL, CHIPREV); + + // + // Read the Part Number. + // + psDevice->ui32ChipPN = AM_REG(MCUCTRL, CHIP_INFO); + + // + // Read the Chip ID0. + // + psDevice->ui32ChipID0 = AM_REG(MCUCTRL, CHIPID0); + + // + // Read the Chip ID1. + // + psDevice->ui32ChipID1 = AM_REG(MCUCTRL, CHIPID1); + + // + // Read the Chip Revision. + // + psDevice->ui32ChipRev = AM_REG(MCUCTRL, CHIPREV); + + // + // Read the Chip VENDOR ID. + // + psDevice->ui32VendorID = AM_REG(MCUCTRL, VENDORID); + + // + // Qualified from Part Number. + // + psDevice->ui32Qualified = + (psDevice->ui32ChipPN & AM_HAL_MCUCTRL_CHIP_INFO_QUAL_M) >> + AM_HAL_MCUCTRL_CHIP_INFO_QUAL_S; + + // + // Flash size from Part Number. + // + psDevice->ui32FlashSize = + g_am_hal_mcuctrl_flash_size[ + (psDevice->ui32ChipPN & AM_HAL_MCUCTRL_CHIP_INFO_FLASH_SIZE_M) >> + AM_HAL_MCUCTRL_CHIP_INFO_FLASH_SIZE_S]; + + // + // SRAM size from Part Number. + // + psDevice->ui32SRAMSize = + g_am_hal_mcuctrl_flash_size[ + (psDevice->ui32ChipPN & AM_HAL_MCUCTRL_CHIP_INFO_SRAM_SIZE_M) >> + AM_HAL_MCUCTRL_CHIP_INFO_SRAM_SIZE_S]; + + // + // Now, let's look at the JEDEC info. + // The full partnumber is 12 bits total, but is scattered across 2 registers. + // Bits [11:8] are 0xE. + // Bits [7:4] are 0xE for Apollo, 0xD for Apollo2. + // Bits [3:0] are defined differently for Apollo and Apollo2. + // For Apollo, the low nibble is 0x0. + // For Apollo2, the low nibble indicates flash and SRAM size. + // + psDevice->ui32JedecPN = (AM_BFR(JEDEC, PID0, PNL8) << 0); + psDevice->ui32JedecPN |= (AM_BFR(JEDEC, PID1, PNH4) << 8); + + // + // JEPID is the JEP-106 Manufacturer ID Code, which is assigned to Ambiq as + // 0x1B, with parity bit is 0x9B. It is 8 bits located across 2 registers. + // + psDevice->ui32JedecJEPID = (AM_BFR(JEDEC, PID1, JEPIDL) << 0); + psDevice->ui32JedecJEPID |= (AM_BFR(JEDEC, PID2, JEPIDH) << 4); + + // + // CHIPREV is 8 bits located across 2 registers. + // + psDevice->ui32JedecCHIPREV = (AM_BFR(JEDEC, PID2, CHIPREVH4) << 4); + psDevice->ui32JedecCHIPREV |= (AM_BFR(JEDEC, PID3, CHIPREVL4) << 0); + + // + // Let's get the Coresight ID (32-bits across 4 registers) + // For Apollo and Apollo2, it's expected to be 0xB105100D. + // + psDevice->ui32JedecCID = (AM_BFR(JEDEC, CID3, CID) << 24); + psDevice->ui32JedecCID |= (AM_BFR(JEDEC, CID2, CID) << 16); + psDevice->ui32JedecCID |= (AM_BFR(JEDEC, CID1, CID) << 8); + psDevice->ui32JedecCID |= (AM_BFR(JEDEC, CID0, CID) << 0); +} + +//***************************************************************************** +// +//! @brief Enables the fault capture registers. +//! +//! This function enables the DCODEFAULTADDR and ICODEFAULTADDR registers. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_mcuctrl_fault_capture_enable(void) +{ + // + // Enable the Fault Capture registers. + // + AM_BFW(MCUCTRL, FAULTCAPTUREEN, ENABLE, 1); +} + +//***************************************************************************** +// +//! @brief Disables the fault capture registers. +//! +//! This function disables the DCODEFAULTADDR and ICODEFAULTADDR registers. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_mcuctrl_fault_capture_disable(void) +{ + // + // Disable the Fault Capture registers. + // + AM_BFW(MCUCTRL, FAULTCAPTUREEN, ENABLE, 0); +} + +//***************************************************************************** +// +//! @brief Gets the fault status and capture registers. +//! +//! @param psFault is a pointer to a structure that will be used to store all +//! fault info. +//! +//! This function gets the status of the ICODE, DCODE, and SYS bus faults and +//! the addresses associated with the fault. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_mcuctrl_fault_status(am_hal_mcuctrl_fault_t *psFault) +{ + uint32_t ui32FaultStat; + + // + // Read the Fault Status Register. + // + ui32FaultStat = AM_REG(MCUCTRL, FAULTSTATUS); + psFault->bICODE = (ui32FaultStat & AM_REG_MCUCTRL_FAULTSTATUS_ICODE_M); + psFault->bDCODE = (ui32FaultStat & AM_REG_MCUCTRL_FAULTSTATUS_DCODE_M); + psFault->bSYS = (ui32FaultStat & AM_REG_MCUCTRL_FAULTSTATUS_SYS_M); + + // + // Read the DCODE fault capture address register. + // + psFault->ui32DCODE = AM_REG(MCUCTRL, DCODEFAULTADDR); + + // + // Read the ICODE fault capture address register. + // + psFault->ui32ICODE |= AM_REG(MCUCTRL, ICODEFAULTADDR); + + // + // Read the ICODE fault capture address register. + // + psFault->ui32SYS |= AM_REG(MCUCTRL, SYSFAULTADDR); +} + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_mcuctrl.h b/bsp/apollo2/libraries/drivers/hal/am_hal_mcuctrl.h new file mode 100644 index 0000000000..6811006fd6 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_mcuctrl.h @@ -0,0 +1,212 @@ +//***************************************************************************** +// +// am_hal_mcuctrl.h +//! @file +//! +//! @brief Functions for accessing and configuring the MCUCTRL. +//! +//! @addtogroup mcuctrl2 MCU Control (MCUCTRL) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_MCUCTRL_H +#define AM_HAL_MCUCTRL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +// +// Deprecate the am_hal_mcuctrl_bucks_enable() and disable() functions. +// This functionality is now handled in pwrctrl. +// +#define am_hal_mcuctrl_bucks_enable am_hal_pwrctrl_bucks_enable +#define am_hal_mcuctrl_bucks_disable am_hal_pwrctrl_bucks_disable + + +//***************************************************************************** +// +// Define CHIP_INFO fields, which for Apollo2 are not defined in the register +// definitions. +// +//***************************************************************************** +#define AM_HAL_MCUCTRL_CHIP_INFO_CLASS_M 0xFF000000 +#define AM_HAL_MCUCTRL_CHIP_INFO_CLASS_S 24 +#define AM_HAL_MCUCTRL_CHIP_INFO_FLASH_SIZE_M 0x00F00000 +#define AM_HAL_MCUCTRL_CHIP_INFO_FLASH_SIZE_S 20 +#define AM_HAL_MCUCTRL_CHIP_INFO_SRAM_SIZE_M 0x000F0000 +#define AM_HAL_MCUCTRL_CHIP_INFO_SRAM_SIZE_S 16 +#define AM_HAL_MCUCTRL_CHIP_INFO_REV_M 0x0000FF00 +#define AM_HAL_MCUCTRL_CHIP_INFO_REV_S 8 +#define AM_HAL_MCUCTRL_CHIP_INFO_PKG_M 0x000000C0 +#define AM_HAL_MCUCTRL_CHIP_INFO_PKG_S 6 +#define AM_HAL_MCUCTRL_CHIP_INFO_PINS_M 0x00000038 +#define AM_HAL_MCUCTRL_CHIP_INFO_PINS_S 3 +#define AM_HAL_MCUCTRL_CHIP_INFO_TEMP_M 0x00000006 +#define AM_HAL_MCUCTRL_CHIP_INFO_TEMP_S 1 +#define AM_HAL_MCUCTRL_CHIP_INFO_QUAL_M 0x00000001 +#define AM_HAL_MCUCTRL_CHIP_INFO_QUAL_S 0 + +//***************************************************************************** +// +// Apollo Number Decode. +// +//***************************************************************************** +extern const uint32_t g_am_hal_mcuctrl_flash_size[]; +extern const uint32_t g_am_hal_mcuctrl_sram_size[]; + +//***************************************************************************** +// +//! MCUCTRL device structure +// +//***************************************************************************** +typedef struct +{ + // + //! Device part number. (BCD format) + // + uint32_t ui32ChipPN; + + // + //! Unique Chip ID 0. + // + uint32_t ui32ChipID0; + + // + //! Unique Chip ID 1. + // + uint32_t ui32ChipID1; + + // + //! Chip Revision. + // + uint32_t ui32ChipRev; + + // + //! Vendor ID. + // + uint32_t ui32VendorID; + + // + //! Qualified chip. + // + uint32_t ui32Qualified; + + // + //! Flash Size. + // + uint32_t ui32FlashSize; + + // + //! SRAM Size. + // + uint32_t ui32SRAMSize; + + // + // JEDEC chip info + // + uint32_t ui32JedecPN; + uint32_t ui32JedecJEPID; + uint32_t ui32JedecCHIPREV; + uint32_t ui32JedecCID; +} +am_hal_mcuctrl_device_t; + +//***************************************************************************** +// +//! MCUCTRL fault structure +// +//***************************************************************************** +typedef struct +{ + // + //! ICODE bus fault occurred. + // + bool bICODE; + + // + //! ICODE bus fault address. + // + uint32_t ui32ICODE; + + // + //! DCODE bus fault occurred. + // + bool bDCODE; + + // + //! DCODE bus fault address. + // + uint32_t ui32DCODE; + + // + //! SYS bus fault occurred. + // + bool bSYS; + + // + //! SYS bus fault address. + // + uint32_t ui32SYS; +} +am_hal_mcuctrl_fault_t; + +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern void am_hal_mcuctrl_device_info_get(am_hal_mcuctrl_device_t *psDevice); +extern void am_hal_mcuctrl_fault_capture_enable(void); +extern void am_hal_mcuctrl_fault_capture_disable(void); +extern void am_hal_mcuctrl_fault_status(am_hal_mcuctrl_fault_t *psFault); + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_MCUCTRL_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_otp.c b/bsp/apollo2/libraries/drivers/hal/am_hal_otp.c new file mode 100644 index 0000000000..67d08448da --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_otp.c @@ -0,0 +1,173 @@ +//***************************************************************************** +// +// am_hal_otp.c +//! @file +//! +//! @brief Functions for handling the OTP interface. +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#include "am_mcu_apollo.h" +#include "am_hal_flash.h" + +//***************************************************************************** +// +//! THIS FUNCTION IS DEPRECATED! +//! Use the respective HAL flash function instead. +//! +// @brief Check if debugger is currently locked out. +// +// @param None. +// +// Determine if the debugger is already locked out. +// +// @return non-zero if debugger is currently locked out. +// Specifically: +// 0 = debugger is not locked out. +// 1 = debugger is locked out. +// +//***************************************************************************** +int +am_hal_otp_is_debugger_lockedout(void) +{ + return am_hal_flash_debugger_disable_check(); +} + +//***************************************************************************** +// +//! THIS FUNCTION IS DEPRECATED! +//! Use the respective HAL flash function instead. +//! +// @brief Lock out debugger access. +// +// @param None. +// +// This function locks out access by a debugger. +// +// @return 0 if lockout was successful or if lockout was already enabled. +// +//***************************************************************************** +int +am_hal_otp_debugger_lockout(void) +{ + return am_hal_flash_debugger_disable(); +} + +//***************************************************************************** +// +//! THIS FUNCTION IS DEPRECATED! +//! Use the respective HAL flash function instead. +//! +// @brief Lock out SRAM access. +// +// @param None. +// +// This function locks out access by a debugger to SRAM. +// +// @return 0 if lockout was successful or if lockout was already enabled. +// Low byte=0xff, byte 1 contains current value of lockout. +// Else, return value from HAL programming function. +// +//***************************************************************************** +int +am_hal_otp_sram_lockout(void) +{ + return am_hal_flash_wipe_sram_enable(); +} + +//***************************************************************************** +// +//! THIS FUNCTION IS DEPRECATED! +//! Use the respective HAL flash function instead. +//! +// @brief Set copy (read) protection. +// +// @param @u32BegAddr The beginning address to be copy protected. +// @u32EndAddr The ending address to be copy protected. +// +// @note For Apollo, the u32BegAddr parameter should be on a 16KB boundary, and +// the u32EndAddr parameter should be on a (16KB-1) boundary. Otherwise +// both parameters will be truncated/expanded to do so. +// For example, if u32BegAddr=0x1000 and u32EndAddr=0xC200, the actual +// range that protected is: 0x0 - 0xFFFF. +// +// This function enables copy protection on a given flash address range. +// +// @return 0 if copy protection was successfully enabled. +// +//***************************************************************************** +int +am_hal_otp_set_copy_protection(uint32_t u32BegAddr, uint32_t u32EndAddr) +{ + return am_hal_flash_copy_protect_set((uint32_t*)u32BegAddr, + (uint32_t*)u32EndAddr); +} + +//***************************************************************************** +// +//! THIS FUNCTION IS DEPRECATED! +//! Use the respective HAL flash function instead. +//! +// @brief Set write protection. +// +// @param @u32BegAddr The beginning address to be write protected. +// @u32EndAddr The ending address to be write protected. +// +// @note For Apollo, the u32BegAddr parameter should be on a 16KB boundary, and +// the u32EndAddr parameter should be on a (16KB-1) boundary. Otherwise +// both parameters will be truncated/expanded to do so. +// For example, if u32BegAddr=0x1000 and u32EndAddr=0xC200, the actual +// range that protected is: 0x0 - 0xFFFF. +// +// This function enables write protection on a given flash address range. +// +// @return 0 if write protection was successfully enabled. +// +//***************************************************************************** +int +am_hal_otp_set_write_protection(uint32_t u32BegAddr, uint32_t u32EndAddr) +{ + return am_hal_flash_write_protect_set((uint32_t*)u32BegAddr, + (uint32_t*)u32EndAddr); +} + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_otp.h b/bsp/apollo2/libraries/drivers/hal/am_hal_otp.h new file mode 100644 index 0000000000..d938e916fb --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_otp.h @@ -0,0 +1,108 @@ +//***************************************************************************** +// +// am_hal_otp.h +//! @file +//! +//! @brief Functions for handling the OTP interface. +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_OTP_H +#define AM_HAL_OTP_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Define some OTP values and macros. +// +//***************************************************************************** +#define AM_HAL_OTP_SIG0 0x00 +#define AM_HAL_OTP_SIG1 0x04 +#define AM_HAL_OTP_SIG2 0x08 +#define AM_HAL_OTP_SIG3 0x0C + +#define AM_HAL_OTP_DBGR_O 0x10 +#define AM_HAL_OTP_WRITPROT0_O 0x20 +#define AM_HAL_OTP_WRITPROT1_O 0x24 +#define AM_HAL_OTP_COPYPROT0_O 0x30 +#define AM_HAL_OTP_COPYPROT1_O 0x34 + +#define AM_HAL_OTP_ADDR 0x50020000 +#define AM_HAL_OTP_DBGRPROT_ADDR (AM_HAL_OTP_ADDR + AM_HAL_OTP_DBGR_O) +#define AM_HAL_OTP_WRITPROT_ADDR (AM_HAL_OTP_ADDR + AM_HAL_OTP_WRITPROT0_O) +#define AM_HAL_OTP_COPYPROT_ADDR (AM_HAL_OTP_ADDR + AM_HAL_OTP_COPYPROT0_O) + +#define AM_HAL_OTP_CHUNKSIZE (16*1024) + +// +// Debugger port lockout macros. +// +#define AM_OTP_DBGR_LOCKOUT_S (0) +#define AM_OTP_DBGR_LOCKOUT_M (0x1 << AM_OTP_DBGR_LOCKOUT_S) +#define AM_OTP_STRM_LOCKOUT_S (1) +#define AM_OTP_STRM_LOCKOUT_M (0x1 << AM_OTP_STRM_LOCKOUT_S) +#define AM_OTP_SRAM_LOCKOUT_S (2) +#define AM_OTP_SRAM_LOCKOUT_M (0x1 << AM_OTP_SRAM_LOCKOUT_S) + +//***************************************************************************** +// +// Function prototypes +// +//***************************************************************************** +extern int am_hal_otp_is_debugger_lockedout(void); +extern int am_hal_otp_debugger_lockout(void); +extern int am_hal_otp_sram_lockout(void); +extern int am_hal_otp_set_copy_protection(uint32_t u32BegAddr, uint32_t u32EndAddr); +extern int am_hal_otp_set_write_protection(uint32_t u32BegAddr, uint32_t u32EndAddr); + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_OTP_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** + diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_pdm.c b/bsp/apollo2/libraries/drivers/hal/am_hal_pdm.c new file mode 100644 index 0000000000..45acfab995 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_pdm.c @@ -0,0 +1,158 @@ +//***************************************************************************** +// +// am_hal_pdm.c +//! @file +//! +//! @brief Functions for interfacing with Pulse Density Modulation (PDM). +//! +//! @addtogroup pdm2 DMEMS Microphon3 (PDM) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +//! @brief Configure the PDM module. +//! +//! This function reads the an \e am_hal_pdm_config_t structure and uses it to +//! set up the PDM module. +//! +//! Please see the information on the am_hal_pdm_config_t configuration +//! structure, found in am_hal_pdm.h, for more information on the parameters +//! that may be set by this function. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_pdm_config(am_hal_pdm_config_t *psConfig) +{ + // + // setup the PDM PCFG register + // + AM_REG(PDM, PCFG) = psConfig->ui32PDMConfigReg; + + // + // setup the PDM VCFG register + // + AM_REG(PDM, VCFG) = psConfig->ui32VoiceConfigReg; + + // + // setup the PDM FIFO Threshold register + // + AM_REG(PDM, FTHR) = psConfig->ui32FIFOThreshold; + + // + // Flush the FIFO for good measure. + // + am_hal_pdm_fifo_flush(); +} + +//***************************************************************************** +// +//! @brief Enable the PDM module. +//! +//! This function enables the PDM module in the mode previously defined by +//! am_hal_pdm_config(). +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_pdm_enable(void) +{ + AM_REG(PDM, PCFG) |= AM_REG_PDM_PCFG_PDMCORE_EN; + AM_REG(PDM, VCFG) |= ( AM_REG_PDM_VCFG_IOCLKEN_EN | + AM_REG_PDM_VCFG_PDMCLK_EN | + AM_REG_PDM_VCFG_RSTB_NORM ); +} + +//***************************************************************************** +// +//! @brief Disable the PDM module. +//! +//! This function disables the PDM module. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_pdm_disable(void) +{ + AM_REG(PDM, PCFG) &= ~ AM_REG_PDM_PCFG_PDMCORE_EN; + AM_REG(PDM, VCFG) &= ~ ( AM_REG_PDM_VCFG_IOCLKEN_EN | + AM_REG_PDM_VCFG_PDMCLK_EN | + AM_REG_PDM_VCFG_RSTB_NORM ); +} + +//***************************************************************************** +// +//! @brief Return the PDM Interrupt status. +//! +//! @param bEnabledOnly - return only the enabled interrupts. +//! +//! Use this function to get the PDM interrupt status. +//! +//! @return intrrupt status +// +//***************************************************************************** +uint32_t +am_hal_pdm_int_status_get(bool bEnabledOnly) +{ + if ( bEnabledOnly ) + { + uint32_t u32RetVal = AM_REG(PDM, INTSTAT); + return u32RetVal & AM_REG(PDM, INTEN); + } + else + { + return AM_REG(PDM, INTSTAT); + } +} + +//***************************************************************************** +// +// End the doxygen group +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_pdm.h b/bsp/apollo2/libraries/drivers/hal/am_hal_pdm.h new file mode 100644 index 0000000000..a6e23d2698 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_pdm.h @@ -0,0 +1,665 @@ +//***************************************************************************** +// +// am_hal_pdm.h +//! @file +//! +//! @brief Functions for accessing and configuring the PDM module +//! +//! @addtogroup pdm2 Pulse Density Modulation (PDM) Input Module. +//! @ingroup apollo2hal +//! @{ + +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#ifndef AM_HAL_PDM_H +#define AM_HAL_PDM_H + +//***************************************************************************** +// +// Macro definitions +// +//***************************************************************************** + +//***************************************************************************** +// +//! @name PDM Left Right Swap Control +//! @brief Macro definitions for the PDM LRSWAP bit field +//! +//! These macros may be used with the am_hal_pdm_config_t structure to set the +//! left right swap bit. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_PCFG_LRSWAP_ENABLE \ + AM_REG_PDM_PCFG_LRSWAP_EN +#define AM_HAL_PDM_PCFG_LRSWAP_DISABLE \ + AM_REG_PDM_PCFG_LRSWAP_NOSWAP +//! @} + +//***************************************************************************** +// +//! @name PDM Right Gain Setting +//! @brief Macro definitions for the PDM Right Gain Setting. +//! +//! These macros may be used with the am_hal_pdm_config_t structure to set the +//! right gain value. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_PCFG_RIGHT_PGA_M15DB AM_REG_PDM_PCFG_PGARIGHT_M15DB +#define AM_HAL_PDM_PCFG_RIGHT_PGA_M300DB AM_REG_PDM_PCFG_PGARIGHT_M300DB +#define AM_HAL_PDM_PCFG_RIGHT_PGA_M45DB AM_REG_PDM_PCFG_PGARIGHT_M45DB +#define AM_HAL_PDM_PCFG_RIGHT_PGA_M60DB AM_REG_PDM_PCFG_PGARIGHT_M60DB +#define AM_HAL_PDM_PCFG_RIGHT_PGA_M75DB AM_REG_PDM_PCFG_PGARIGHT_M75DB +#define AM_HAL_PDM_PCFG_RIGHT_PGA_M90DB AM_REG_PDM_PCFG_PGARIGHT_M90DB +#define AM_HAL_PDM_PCFG_RIGHT_PGA_M105DB AM_REG_PDM_PCFG_PGARIGHT_M105DB +#define AM_HAL_PDM_PCFG_RIGHT_PGA_M120DB AM_REG_PDM_PCFG_PGARIGHT_M120DB +#define AM_HAL_PDM_PCFG_RIGHT_PGA_P105DB AM_REG_PDM_PCFG_PGARIGHT_P105DB +#define AM_HAL_PDM_PCFG_RIGHT_PGA_P90DB AM_REG_PDM_PCFG_PGARIGHT_P90DB +#define AM_HAL_PDM_PCFG_RIGHT_PGA_P75DB AM_REG_PDM_PCFG_PGARIGHT_P75DB +#define AM_HAL_PDM_PCFG_RIGHT_PGA_P60DB AM_REG_PDM_PCFG_PGARIGHT_P60DB +#define AM_HAL_PDM_PCFG_RIGHT_PGA_P45DB AM_REG_PDM_PCFG_PGARIGHT_P45DB +#define AM_HAL_PDM_PCFG_RIGHT_PGA_P300DB AM_REG_PDM_PCFG_PGARIGHT_P300DB +#define AM_HAL_PDM_PCFG_RIGHT_PGA_P15DB AM_REG_PDM_PCFG_PGARIGHT_P15DB +#define AM_HAL_PDM_PCFG_RIGHT_PGA_0DB AM_REG_PDM_PCFG_PGARIGHT_0DB +//! @} + +//***************************************************************************** +// +//! @name PDM Left Gain Setting +//! @brief Macro definitions for the PDM Left Gain Setting. +//! +//! These macros may be used with the am_hal_pdm_config_t structure to set the +//! left gain value. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_PCFG_LEFT_PGA_M15DB AM_REG_PDM_PCFG_PGALEFT_M15DB +#define AM_HAL_PDM_PCFG_LEFT_PGA_M300DB AM_REG_PDM_PCFG_PGALEFT_M300DB +#define AM_HAL_PDM_PCFG_LEFT_PGA_M45DB AM_REG_PDM_PCFG_PGALEFT_M45DB +#define AM_HAL_PDM_PCFG_LEFT_PGA_M60DB AM_REG_PDM_PCFG_PGALEFT_M60DB +#define AM_HAL_PDM_PCFG_LEFT_PGA_M75DB AM_REG_PDM_PCFG_PGALEFT_M75DB +#define AM_HAL_PDM_PCFG_LEFT_PGA_M90DB AM_REG_PDM_PCFG_PGALEFT_M90DB +#define AM_HAL_PDM_PCFG_LEFT_PGA_M105DB AM_REG_PDM_PCFG_PGALEFT_M105DB +#define AM_HAL_PDM_PCFG_LEFT_PGA_M120DB AM_REG_PDM_PCFG_PGALEFT_M120DB +#define AM_HAL_PDM_PCFG_LEFT_PGA_P105DB AM_REG_PDM_PCFG_PGALEFT_P105DB +#define AM_HAL_PDM_PCFG_LEFT_PGA_P90DB AM_REG_PDM_PCFG_PGALEFT_P90DB +#define AM_HAL_PDM_PCFG_LEFT_PGA_P75DB AM_REG_PDM_PCFG_PGALEFT_P75DB +#define AM_HAL_PDM_PCFG_LEFT_PGA_P60DB AM_REG_PDM_PCFG_PGALEFT_P60DB +#define AM_HAL_PDM_PCFG_LEFT_PGA_P45DB AM_REG_PDM_PCFG_PGALEFT_P45DB +#define AM_HAL_PDM_PCFG_LEFT_PGA_P300DB AM_REG_PDM_PCFG_PGALEFT_P300DB +#define AM_HAL_PDM_PCFG_LEFT_PGA_P15DB AM_REG_PDM_PCFG_PGALEFT_P15DB +#define AM_HAL_PDM_PCFG_LEFT_PGA_0DB AM_REG_PDM_PCFG_PGALEFT_0DB +//! @} + +//***************************************************************************** +// +//! @name PDM Configuration MCLK Divider +//! @brief Macro definitions for the PDM MCLK Divider +//! +//! These macros may be used with the am_hal_pdm_config_t structure to set the +//! sinc decimation rate relative to the PDM sample clock (OSR). +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_PCFG_MCLKDIV_DIV1 AM_REG_PDM_PCFG_MCLKDIV_MCKDIV1 +#define AM_HAL_PDM_PCFG_MCLKDIV_DIV2 AM_REG_PDM_PCFG_MCLKDIV_MCKDIV2 +#define AM_HAL_PDM_PCFG_MCLKDIV_DIV3 AM_REG_PDM_PCFG_MCLKDIV_MCKDIV3 +#define AM_HAL_PDM_PCFG_MCLKDIV_DIV4 AM_REG_PDM_PCFG_MCLKDIV_MCKDIV4 + +#define AM_HAL_PDM_PCFG_MCLKDIV(DIV) AM_REG_PDM_PCFG_MCLKDIV(DIV) +//! @} + +//***************************************************************************** +// +//! @name PDM Configuration SINC Decimation Rate +//! @brief Macro definitions for the PDM SINC decimation rate +//! +//! These macros may be used with the am_hal_pdm_config_t structure to set the +//! sinc decimation rate relative to the PDM sample clock (OSR). +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_PCFG_SINC_RATE(OSR) \ + AM_REG_PDM_PCFG_SINCRATE(OSR) +//! @} + +//***************************************************************************** +// +//! @name PDM Configuration High Pass Filter Enable +//! @brief Macro definitions for the PDM ADCHPD +//! +//! These macros may be used with the am_hal_pdm_config_t structure to enable +//! the high pass filter. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_PCFG_ADCHPD_ENABLE AM_REG_PDM_PCFG_ADCHPD_EN +#define AM_HAL_PDM_PCFG_ADCHPD_DISABLE AM_REG_PDM_PCFG_ADCHPD_DIS +//! @} + +//***************************************************************************** +// +//! @name PDM Configuration HPCUTOFF +//! @brief Macro definitions for the PDM High Pass Filter Cutoff Selector. +//! +//! These macros may be used with the am_hal_pdm_config_t structure to set the +//! high pass filter cutoff frequency. Valid range is 0 to 7. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_PCFG_HPCUTOFF(HPSEL) \ + AM_REG_PDM_PCFG_HPCUTOFF(HPSEL) +//! @} + +//***************************************************************************** +// +//! @name PDM Configuration Gain Set Change Clock Delay +//! @brief Macro definitions for the PDM clock delay for gain set changes. +//! +//! These macros may be used with the am_hal_pdm_config_t structure to set the +//! number of clocks for spreading gain setting changes. Valid range is 0 to 7. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_PCFG_CYCLES(CLOCKS) \ + AM_REG_PDM_PCFG_CYCLES(CLOCKS) +//! @} + +//***************************************************************************** +// +//! @name PDM Configuration SOFTMUTE enable/disable. +//! @brief Macro definitions for the PDM PCFG register mute controls. +//! +//! These macros may be used with the am_hal_pdm_config_t structure to enable +//! or disable the SOFTMUTE option. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_PCFG_SOFTMUTE_ENABLE AM_REG_PDM_PCFG_SOFTMUTE_EN +#define AM_HAL_PDM_PCFG_SOFTMUTE_DISABLE AM_REG_PDM_PCFG_SOFTMUTE_DIS +//! @} + +//***************************************************************************** +// +//! @name PDM Configuration PDM Core enable/disable. +//! @brief Macro definitions for the PDM PCFG register filter engine enable. +//! +//! These macros may be used with the am_hal_pdm_config_t structure to enable +//! or disable the PDM filter engine core. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_PCFG_PDMCORE_ENABLE AM_REG_PDM_PCFG_PDMCORE_EN +#define AM_HAL_PDM_PCFG_PDMCORE_DISABLE AM_REG_PDM_PCFG_PDMCORE_DIS +//! @} + +//***************************************************************************** +// +//! @name PDM Clock Frequencies +//! @brief Macro definitions for the PDM clock (from clkgen) frequencies. +//! +//! These macros may be used with the am_hal_pdm_config_t structure to set the +//! source clock frequency of the PDM interface. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_IOCLK_12MHZ \ + (AM_REG_PDM_VCFG_PDMCLKSEL_12MHz | AM_REG_PDM_VCFG_IOCLKEN_EN) +#define AM_HAL_PDM_IOCLK_6MHZ \ + (AM_REG_PDM_VCFG_PDMCLKSEL_6MHz | AM_REG_PDM_VCFG_IOCLKEN_EN) +#define AM_HAL_PDM_IOCLK_3MHZ \ + (AM_REG_PDM_VCFG_PDMCLKSEL_3MHz | AM_REG_PDM_VCFG_IOCLKEN_EN) +#define AM_HAL_PDM_IOCLK_1_5MHZ \ + (AM_REG_PDM_VCFG_PDMCLKSEL_1_5MHz | AM_REG_PDM_VCFG_IOCLKEN_EN) +#define AM_HAL_PDM_IOCLK_750KHZ \ + (AM_REG_PDM_VCFG_PDMCLKSEL_750KHz | AM_REG_PDM_VCFG_IOCLKEN_EN) +#define AM_HAL_PDM_IOCLK_375KHZ \ + (AM_REG_PDM_VCFG_PDMCLKSEL_375KHz | AM_REG_PDM_VCFG_IOCLKEN_EN) +#define AM_HAL_PDM_IOCLK_187KHZ \ + (AM_REG_PDM_VCFG_PDMCLKSEL_187KHz | AM_REG_PDM_VCFG_IOCLKEN_EN) +//! @} + +//***************************************************************************** +// +//! @name PDM Voice Configuration RSTB +//! @brief Reset the IP core. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_VCFG_RSTB_RESET AM_REG_PDM_VCFG_RSTB_RESET +#define AM_HAL_PDM_VCFG_RSTB_NORMAL AM_REG_PDM_VCFG_RSTB_NORM +//! @} + +//***************************************************************************** +// +//! @name PDM Voice Configuration PDM Clock Enable/Disable +//! @brief Macro definitions for the PDM VCFG register PDMCLKEN. +//! +//! These macros may be used with the am_hal_pdm_config_t structure to enable +//! or disable the PDM clock output to the pad mux and from there to the world. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_VCFG_PDMCLK_ENABLE AM_REG_PDM_VCFG_PDMCLK_EN +#define AM_HAL_PDM_VCFG_PDMCLK_DISABLE AM_REG_PDM_VCFG_PDMCLK_DIS +//! @} + +//***************************************************************************** +// +//! @name PDM Voice Configuration I2S Mode Enable/Disable +//! @brief Macro definitions for the PDM VCFG register I2SMODE. +//! +//! These macros may be used with the am_hal_pdm_config_t structure to enable +//! or disable the PDM clock output to the pad mux and from there to the world. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_VCFG_I2SMODE_ENABLE AM_REG_PDM_VCFG_I2SMODE_EN +#define AM_HAL_PDM_VCFG_I2SMODE_DISABLE AM_REG_PDM_VCFG_I2SMODE_DIS +//! @} + +//***************************************************************************** +// +//! @name PDM Voice Configuration BCLK Inversion Enable/Disable +//! @brief Macro definitions for the PDM VCFG register BCLKINV. +//! +//! These macros may be used with the am_hal_pdm_config_t structure to enable +//! or disable the PDM clock output to the pad mux and from there to the world. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_VCFG_BCLKINV_ENABLE AM_REG_PDM_VCFG_BCLKINV_INV +#define AM_HAL_PDM_VCFG_BCLKINV_DISABLE AM_REG_PDM_VCFG_BCLKINV_NORM +//! @} + +//***************************************************************************** +// +//! @name PDM Voice Configuration DMICDEL Enable/Disable +//! @brief Macro definitions for the PDM VCFG register Digital Mic Delay. +//! +//! These macros may be used with the am_hal_pdm_config_t structure to enable +//! or disable the PDM digital microphone clock delay. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_VCFG_DMICDEL_1CYC AM_REG_PDM_VCFG_DMICKDEL_1CYC +#define AM_HAL_PDM_VCFG_DMICDEL_0CYC AM_REG_PDM_VCFG_DMICKDEL_0CYC +#define AM_HAL_PDM_VCFG_DMICDEL_ENABLE AM_REG_PDM_VCFG_DMICKDEL_1CYC +#define AM_HAL_PDM_VCFG_DMICDEL_DISABLE AM_REG_PDM_VCFG_DMICKDEL_0CYC +//! @} + +//***************************************************************************** +// +//! @name PDM Voice Configuration Select Apps Processor (AP) versus Internal +//! @brief Macro definitions for the PDM VCFG register Digital Mic Delay. +//! +//! These macros may be used with the am_hal_pdm_config_t structure to select +//! the Application Processor (I2S slave) mode or the Internal FIFO interface +//! to the Apollo Cortex M4. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_VCFG_SELAP_I2S AM_REG_PDM_VCFG_SELAP_I2S +#define AM_HAL_PDM_VCFG_SELAP_INTERNAL AM_REG_PDM_VCFG_SELAP_INTERNAL +#define AM_HAL_PDM_VCFG_SELAP_AP_I2S AM_REG_PDM_VCFG_SELAP_I2S +#define AM_HAL_PDM_VCFG_SELAP_CM4_FIFO AM_REG_PDM_VCFG_SELAP_INTERNAL +//! @} + +//***************************************************************************** +// +//! @name PDM Voice Configuration PACK Enable/Disable +//! @brief Macro definitions for the PDM VCFG register sample packing mode. +//! +//! These macros may be used with the am_hal_pdm_config_t structure to enable +//! or disable the PDM sample packing mode. This mode puts two 16-bit samples +//! per 32-bit FIFO word. The following packed modes are available: +//! +//! mono left: LEFT_NEW, LEFT_OLD +//! mono right: RIGHT_NEW,RIGHT_OLD +//! stereo right: LEFT, RIGHT +//! stereo right(LRSWAP): RIGHT, LEFT +//! +//! +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_VCFG_PACK_ENABLE AM_REG_PDM_VCFG_PCMPACK_EN +#define AM_HAL_PDM_VCFG_PACK_DISABLE AM_REG_PDM_VCFG_PCMPACK_DIS +//! @} + +//***************************************************************************** +// +//! @name PDM Channel Selects +//! @brief Macro definitions for the PDM Channel Selection. +//! +//! These macros may be used with the am_hal_pdm_config_t structure to set the +//! channel selection for the PDM interface. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_VCFG_CHANNEL_LEFT AM_REG_PDM_VCFG_CHSET_LEFT +#define AM_HAL_PDM_VCFG_CHANNEL_RIGHT AM_REG_PDM_VCFG_CHSET_RIGHT +#define AM_HAL_PDM_VCFG_CHANNEL_STEREO AM_REG_PDM_VCFG_CHSET_STEREO +//! @} + +//***************************************************************************** +// +//! @name PDM Interrupts +//! @brief Macro definitions for the PDM interrupt status bits. +//! +//! These macros correspond to the bits in the PDM interrupt status register. +//! They may be used for any of the am_hal_pdm_int_x() functions. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_PDM_INT_UNDFL AM_REG_PDM_INTEN_UNDFL_M +#define AM_HAL_PDM_INT_OVF AM_REG_PDM_INTEN_OVF_M +#define AM_HAL_PDM_INT_FIFO AM_REG_PDM_INTEN_THR_M +//! @} + +//***************************************************************************** +// +//! @brief Configuration structure for the PDM module. +// +//***************************************************************************** +typedef struct +{ + // + //! @brief Set the PDM configuration reg with the values in this member. + //! Choose from AM_HAL_PDM_PCFG macros. + //! AM_HAL_PDM_PCFG_LRSWAP_xxx + //! AM_HAL_PDM_PCFG_RIGHT_PGA_xxx + //! AM_HAL_PDM_PCFG_LEFT_PGA_xxx + //! AM_HAL_PDM_PCFG_MCLKDIV_xxx + //! AM_HAL_PDM_PCFG_SINC_RATE() + //! AM_HAL_PDM_PCFG_ADCHPD_xxx + //! AM_HAL_PDM_PCFG_HPCUTOFF() + //! AM_HAL_PDM_PCFG_CYCLES() + //! AM_HAL_PDM_PCFG_SOFTMUTE_xxx + //! * AM_HAL_PDM_PCFG_PDMCORE_EN + //! AM_HAL_PDM_PCFG_PDMCORE_DISABLE + // + uint32_t ui32PDMConfigReg; + + // + //! @brief Set the Voice Configuration reg with the values in this member. + //! Choose from AM_HAL_PDM_VCFG macros. + //! AM_HAL_PDM_IOCLK_xxx (also sets AM_REG_PDM_VCFG_IOCLKEN_EN) + //! * AM_REG_PDM_VCFG_IOCLKEN_EN + //! * AM_HAL_PDM_VCFG_RSTB_RESET + //! AM_HAL_PDM_VCFG_RSTB_NORMAL + //! * AM_HAL_PDM_VCFG_PDMCLK_EN + //! AM_HAL_PDM_VCFG_PDMCLK_DIS + //! AM_HAL_PDM_VCFG_I2SMODE_xxx + //! AM_HAL_PDM_VCFG_BCLKINV_xxx + //! AM_HAL_PDM_VCFG_DMICDEL_xxx + //! AM_HAL_PDM_VCFG_SELAP_xxx + //! AM_HAL_PDM_VCFG_PACK_xxx + //! AM_HAL_PDM_VCFG_CHANNEL_xxx + //! + //! * = These bits are set or cleared by the HAL PDM functions + //! am_hal_pdm_enable() or am_hal_pdm_disable(). + // + uint32_t ui32VoiceConfigReg; + + // + //! @brief Select the FIFO PCM sample threshold. + //! + //! The PDM controller will generate a processor interrupt when the number + //! of entries in the FIFO goes *above* this number. + // + uint32_t ui32FIFOThreshold; +} am_hal_pdm_config_t; + +//***************************************************************************** +// +// Define function-like macros. +// +//***************************************************************************** + +//***************************************************************************** +// +//! @brief Read the FIFO depth information as an in-line macro +// +//***************************************************************************** +#define am_hal_pdm_fifo_depth_read() (AM_REG(PDM, FR)) + +//***************************************************************************** +// +//! @brief Read the FIFO READ DATA as an in-line macro +// +//***************************************************************************** +#define am_hal_pdm_fifo_data_read() (AM_REG(PDM, FRD)) + +//***************************************************************************** +// +//! @brief Flush the FIFO as an in-line macro +// +//***************************************************************************** +#define am_hal_pdm_fifo_flush() (AM_REG(PDM, FLUSH) = 0) + +//***************************************************************************** +// +//! @brief Set the PDM Configuration (PCFG) Register +//! +//! This function sets the PDM configuration register +// +//***************************************************************************** +#define am_hal_pdm_pcfg_set(Value) (AM_REG(PDM, PCFG) = Value) + +//***************************************************************************** +// +//! @brief Get the PCFG register value from PDM module. +// +//***************************************************************************** +#define am_hal_pdm_pcfg_get() (AM_REG(PDM, PCFG)) + +//***************************************************************************** +// +//! @brief Set the Voice Configuration (VCFG) Register +// +//***************************************************************************** +#define am_hal_pdm_vcfg_set(Value) (AM_REG(PDM, VCFG) = Value) + +//***************************************************************************** +// +//! @brief Get the VCFG register value from PDM module. +// +//***************************************************************************** +#define am_hal_pdm_vcfg_get() (AM_REG(PDM, VCFG)) + +//***************************************************************************** +// +//! @brief Set the FIFO Threshold +// +//***************************************************************************** +#define am_hal_pdm_thresh_set(thresh) (AM_REG(PDM, FTHR) = thresh) + +//***************************************************************************** +// +//! @brief Get the FIFO Threshold register value from PDM module. +// +//***************************************************************************** +#define am_hal_pdm_thresh_get() (AM_REG(PDM, FTHR)) + +//***************************************************************************** +// +//! @brief Set the left microphone PGA gain. +//! +//***************************************************************************** +#define am_hal_pdm_left_gain_set(gain) (AM_BFW(PDM, PCFG, PGALEFT, gain)) + +//***************************************************************************** +// +//! @brief Set the right microphone PGA gain. +// +//***************************************************************************** +#define am_hal_pdm_right_gain_set(gain) (AM_BFW(PDM, PCFG, PGARIGHT, gain)) + +//***************************************************************************** +// +//! @brief Get the left microphone PGA gain value. +// +//***************************************************************************** +#define am_hal_pdm_left_gain_get() (AM_BFR(PDM, PCFG, PGALEFT)) + +//***************************************************************************** +// +//! @brief Get the right microphone PGA gain value. +// +//***************************************************************************** +#define am_hal_pdm_right_gain_get() (AM_BFR(PDM, PCFG, PGARIGHT)) + +//***************************************************************************** +// +//! @brief Enable the Soft Mute functionality. +// +//***************************************************************************** +#define am_hal_pdm_soft_mute_enable() (AM_BFWe(PDM, PCFG, SOFTMUTE, EN)) + +//***************************************************************************** +// +//! @brief Disable the Soft Mute functionality. +// +//***************************************************************************** +#define am_hal_pdm_soft_mute_disable() (AM_BFWe(PDM, PCFG, SOFTMUTE, DIS)) + +//***************************************************************************** +// +//! @brief Enable selected PDM Interrupts. +//! +//! @param ui32Interrupt - Use the macro bit fields provided in am_hal_pdm.h\n +//! AM_HAL_PDM_INT_UNDFL\n +//! AM_HAL_PDM_INT_OVF\n +//! AM_HAL_PDM_INT_FIFO\n +// +//***************************************************************************** +#define am_hal_pdm_int_enable(intrpt) (AM_REG(PDM, INTEN) |= intrpt) + +//***************************************************************************** +// +//! @brief Return the enabled PDM Interrupts. +//! +//! Use this function to return all enabled PDM interrupts. +//! +//! @return all enabled PDM interrupts as a mask.\n +//! AM_HAL_PDM_INT_UNDFL\n +//! AM_HAL_PDM_INT_OVF\n +//! AM_HAL_PDM_INT_FIFO\n +// +//***************************************************************************** +#define am_hal_pdm_int_enable_get() (AM_REG(PDM, INTEN)) + +//***************************************************************************** +// +//! @brief Disable selected PDM Interrupts. +//! +//! @param ui32Interrupt - Use the macro bit fields provided in am_hal_pdm.h\n +//! AM_HAL_PDM_INT_UNDFL\n +//! AM_HAL_PDM_INT_OVF\n +//! AM_HAL_PDM_INT_FIFO\n +// +//***************************************************************************** +#define am_hal_pdm_int_disable(intrpt) (AM_REG(PDM, INTEN) &= ~intrpt) + +//***************************************************************************** +// +//! @brief Clear selected PDM Interrupts. +//! +//! @param ui32Interrupt - Use the macro bit fields provided in am_hal_pdm.h\n +//! AM_HAL_PDM_INT_UNDFL\n +//! AM_HAL_PDM_INT_OVF\n +//! AM_HAL_PDM_INT_FIFO\n +// +//***************************************************************************** +#define am_hal_pdm_int_clear(intrpt) (AM_REG(PDM, INTCLR) = intrpt) + +//***************************************************************************** +// +//! @brief Set selected PDM Interrupts. +//! +//! Use this function to set the PDM interrupts. +//! +//! @param ui32Interrupt - Use the macro bit fields provided in am_hal_pdm.h\n +//! AM_HAL_PDM_INT_UNDFL\n +//! AM_HAL_PDM_INT_OVF\n +//! AM_HAL_PDM_INT_FIFO\n +// +//***************************************************************************** +#define am_hal_pdm_int_set(intrpt) (AM_REG(PDM, INTSET) = intrpt) + +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern void am_hal_pdm_config(am_hal_pdm_config_t * cfg); +extern void am_hal_pdm_enable(void); +extern void am_hal_pdm_disable(void); + +extern uint32_t am_hal_pdm_int_status_get(bool bEnabledOnly); + +#endif // AM_HAL_PDM_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_pin.h b/bsp/apollo2/libraries/drivers/hal/am_hal_pin.h new file mode 100644 index 0000000000..8a1068f882 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_pin.h @@ -0,0 +1,557 @@ +//***************************************************************************** +// +// am_hal_pin.h +//! @file +//! @brief Macros for configuring specific pins. +//! +//! @addtogroup pin2 PIN definitions for Apollo2. +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#ifndef AM_HAL_PIN_H +#define AM_HAL_PIN_H + +//***************************************************************************** +// +// Pin definition helper macros. +// +//***************************************************************************** +#define AM_HAL_PIN_DIR_INPUT (AM_HAL_GPIO_INPEN) +#define AM_HAL_PIN_DIR_OUTPUT (AM_HAL_GPIO_OUT_PUSHPULL) +#define AM_HAL_PIN_DIR_OPENDRAIN (AM_HAL_GPIO_OUT_OPENDRAIN | AM_HAL_GPIO_INPEN) +#define AM_HAL_PIN_DIR_3STATE (AM_HAL_GPIO_OUT_3STATE) + +//***************************************************************************** +// +// Pin definition helper macros. +// +//***************************************************************************** +#define AM_HAL_PIN_DISABLE (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_INPUT (AM_HAL_GPIO_FUNC(3) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_OUTPUT (AM_HAL_GPIO_FUNC(3) | AM_HAL_PIN_DIR_OUTPUT) +#define AM_HAL_PIN_OPENDRAIN (AM_HAL_GPIO_FUNC(3) | AM_HAL_PIN_DIR_OPENDRAIN) +#define AM_HAL_PIN_3STATE (AM_HAL_GPIO_FUNC(3) | AM_HAL_PIN_DIR_3STATE) + +//***************************************************************************** +// +// Pin definition macros. +// +//***************************************************************************** +#define AM_HAL_PIN_0_SLSCL (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_0_SLSCK (AM_HAL_GPIO_FUNC(1) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_0_CLKOUT (AM_HAL_GPIO_FUNC(2)) +#define AM_HAL_PIN_0_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_0_MxSCKLB (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_0_M2SCK (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_0_MxSCLLB (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_0_M2SCL (AM_HAL_GPIO_FUNC(7) | AM_HAL_PIN_DIR_OPENDRAIN) + +#define AM_HAL_PIN_1_SLSDA (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_OPENDRAIN) +#define AM_HAL_PIN_1_SLMISO (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_1_UART0TX (AM_HAL_GPIO_FUNC(2)) +#define AM_HAL_PIN_1_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_1_MxMISOLB (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_1_M2MISO (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_1_MxSDALB (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_1_M2SDA (AM_HAL_GPIO_FUNC(7) | AM_HAL_PIN_DIR_OPENDRAIN) + +#define AM_HAL_PIN_2_SLWIR3 (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_3STATE) +#define AM_HAL_PIN_2_SLMOSI (AM_HAL_GPIO_FUNC(1) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_2_UART0RX (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_2_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_2_MxMOSILB (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_2_M2MOSI (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_2_MxWIR3LB (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_2_M2WIR3 (AM_HAL_GPIO_FUNC(7) | AM_HAL_PIN_DIR_3STATE) + +#define AM_HAL_PIN_3_UART0RTS (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_3_SLnCE (AM_HAL_GPIO_FUNC(1) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_3_M1nCE4 (AM_HAL_GPIO_FUNC(2)) +#define AM_HAL_PIN_3_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_3_MxnCELB (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_3_M2nCE0 (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_3_TRIG1 (AM_HAL_GPIO_FUNC(6) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_3_I2S_WCLK (AM_HAL_GPIO_FUNC(7)) +#define AM_HAL_PIN_3_PSOURCE (AM_HAL_GPIO_FUNC(3) | AM_HAL_PIN_DIR_OUTPUT | AM_HAL_GPIO_POWER) + +#define AM_HAL_PIN_4_UART0CTS (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_4_SLINT (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_4_M0nCE5 (AM_HAL_GPIO_FUNC(2)) +#define AM_HAL_PIN_4_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_4_SLINTGP (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_4_M2nCE5 (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_4_CLKOUT (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_4_32KHZ_XT (AM_HAL_GPIO_FUNC(7)) + +#define AM_HAL_PIN_5_M0SCL (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_OPENDRAIN) +#define AM_HAL_PIN_5_M0SCK (AM_HAL_GPIO_FUNC(1) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_5_UART0RTS (AM_HAL_GPIO_FUNC(2)) +#define AM_HAL_PIN_5_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_5_M0SCKLB (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_5_EXTHFA (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_5_M0SCLLB (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_5_M1nCE2 (AM_HAL_GPIO_FUNC(7)) + +#define AM_HAL_PIN_6_M0SDA (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_OPENDRAIN) +#define AM_HAL_PIN_6_M0MISO (AM_HAL_GPIO_FUNC(1) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_6_UART0CTS (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_6_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_6_SLMISOLB (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_6_M1nCE0 (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_6_SLSDALB (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_6_I2S_DAT (AM_HAL_GPIO_FUNC(7)) + +#define AM_HAL_PIN_7_M0WIR3 (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_3STATE) +#define AM_HAL_PIN_7_M0MOSI (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_7_CLKOUT (AM_HAL_GPIO_FUNC(2)) +#define AM_HAL_PIN_7_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_7_TRIG0 (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_7_UART0TX (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_7_SLWIR3LB (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_7_M1nCE1 (AM_HAL_GPIO_FUNC(7)) + +#define AM_HAL_PIN_8_M1SCL (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_OPENDRAIN) +#define AM_HAL_PIN_8_M1SCK (AM_HAL_GPIO_FUNC(1) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_8_M0nCE4 (AM_HAL_GPIO_FUNC(2)) +#define AM_HAL_PIN_8_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_8_M2nCE4 (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_8_M1SCKLB (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_8_UART1TX (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_8_M1SCLLB (AM_HAL_GPIO_FUNC(7)) + +#define AM_HAL_PIN_9_M1SDA (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_OPENDRAIN) +#define AM_HAL_PIN_9_M1MISO (AM_HAL_GPIO_FUNC(1) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_9_M0nCE5 (AM_HAL_GPIO_FUNC(2)) +#define AM_HAL_PIN_9_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_9_M4nCE5 (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_9_SLMISOLB (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_9_UART1RX (AM_HAL_GPIO_FUNC(6) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_9_SLSDALB (AM_HAL_GPIO_FUNC(7)) + +#define AM_HAL_PIN_10_M1WIR3 (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_3STATE) +#define AM_HAL_PIN_10_M1MOSI (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_10_M0nCE6 (AM_HAL_GPIO_FUNC(2)) +#define AM_HAL_PIN_10_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_10_M2nCE6 (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_10_UART1RTS (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_10_M4nCE4 (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_10_SLWIR3LB (AM_HAL_GPIO_FUNC(7)) + +#define AM_HAL_PIN_11_ADCSE2 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_11_M0nCE0 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_11_CLKOUT (AM_HAL_GPIO_FUNC(2)) +#define AM_HAL_PIN_11_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_11_M2nCE7 (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_11_UART1CTS (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_11_UART0RX (AM_HAL_GPIO_FUNC(6) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_11_PDM_DATA (AM_HAL_GPIO_FUNC(7) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_11_PSINK (AM_HAL_GPIO_FUNC(3)) + +#define AM_HAL_PIN_12_ADCD0NSE9 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_12_M1nCE0 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_12_TCTA0 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_12_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_12_CLKOUT (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_12_PDM_CLK (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_12_UART0CTS (AM_HAL_GPIO_FUNC(6) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_12_UART1TX (AM_HAL_GPIO_FUNC(7)) + +#define AM_HAL_PIN_13_ADCD0PSE8 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_13_M1nCE1 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_13_TCTB0 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_13_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_13_M2nCE3 (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_13_EXTHFB (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_13_UART0RTS (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_13_UART1RX (AM_HAL_GPIO_FUNC(7) | AM_HAL_PIN_DIR_INPUT) + +#define AM_HAL_PIN_14_ADCD1P (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_14_M1nCE2 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_14_UART1TX (AM_HAL_GPIO_FUNC(2)) +#define AM_HAL_PIN_14_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_14_M2nCE1 (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_14_EXTHFS (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_14_SWDCK (AM_HAL_GPIO_FUNC(6) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_14_32KHZ_XT (AM_HAL_GPIO_FUNC(7)) + +#define AM_HAL_PIN_15_ADCD1N (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_15_M1nCE3 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_15_UART1RX (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_15_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_15_M2nCE2 (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_15_EXTXT (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_15_SWDIO (AM_HAL_GPIO_FUNC(6) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_15_SWO (AM_HAL_GPIO_FUNC(7)) + +#define AM_HAL_PIN_16_ADCSE0 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_16_M0nCE4 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_16_TRIG0 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_16_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_16_M2nCE3 (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_16_CMPIN0 (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_16_UART0TX (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_16_UART1RTS (AM_HAL_GPIO_FUNC(7)) + +#define AM_HAL_PIN_17_CMPRF1 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_17_M0nCE1 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_17_TRIG1 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_17_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_17_M4nCE3 (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_17_EXTLF (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_17_UART0RX (AM_HAL_GPIO_FUNC(6) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_17_UART1CTS (AM_HAL_GPIO_FUNC(7) | AM_HAL_PIN_DIR_INPUT) + +#define AM_HAL_PIN_18_CMPIN1 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_18_M0nCE2 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_18_TCTA1 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_18_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_18_M4nCE1 (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_18_ANATEST2 (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_18_UART1TX (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_18_32KHZ_XT (AM_HAL_GPIO_FUNC(7)) + +#define AM_HAL_PIN_19_CMPRF0 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_19_M0nCE3 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_19_TCTB1 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_19_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_19_TCTA1 (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_19_ANATEST1 (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_19_UART1RX (AM_HAL_GPIO_FUNC(6) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_19_I2S_BCLK (AM_HAL_GPIO_FUNC(7)) + +#define AM_HAL_PIN_20_SWDCK (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_20_M1nCE5 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_20_TCTA2 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_20_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_20_UART0TX (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_20_UART1TX (AM_HAL_GPIO_FUNC(5)) + +#define AM_HAL_PIN_21_SWDIO (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_21_M1nCE6 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_21_TCTB2 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_21_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_21_UART0RX (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_21_UART1RX (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) + +#define AM_HAL_PIN_22_UART0TX (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_22_M1nCE7 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_22_TCTA3 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_22_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_22_PDM_CLK (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_22_TCTB1 (AM_HAL_GPIO_FUNC(6) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_22_SWO (AM_HAL_GPIO_FUNC(7)) +#define AM_HAL_PIN_22_PSOURCE (AM_HAL_GPIO_FUNC(3) | AM_HAL_PIN_DIR_OUTPUT | AM_HAL_GPIO_POWER) + +#define AM_HAL_PIN_23_UART0RX (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_23_M0nCE0 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_23_TCTB3 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_23_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_23_PDM_DATA (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_23_CMPOUT (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_23_TCTB1 (AM_HAL_GPIO_FUNC(6) | AM_HAL_PIN_DIR_INPUT) + +#if defined (AM_PACKAGE_BGA) +#define AM_HAL_PIN_24_M2nCE1 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_24_M0nCE1 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_24_CLKOUT (AM_HAL_GPIO_FUNC(2)) +#define AM_HAL_PIN_24_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_24_M5nCE0 (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_24_TCTA1 (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_24_I2S_BCLK (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_24_SWO (AM_HAL_GPIO_FUNC(7)) +#endif // defined (AM_PACKAGE_BGA) + +#if defined (AM_PACKAGE_BGA) +#define AM_HAL_PIN_25_EXTXT (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_25_M0nCE2 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_25_TCTA0 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_25_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_25_M2SDA (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_OPENDRAIN) +#define AM_HAL_PIN_25_M2MISO (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_25_SLMISOLB (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_25_SLSDALB (AM_HAL_GPIO_FUNC(7)) +#endif // defined (AM_PACKAGE_BGA) + +#define AM_HAL_PIN_26_EXTLF (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_26_M0nCE3 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_26_TCTB0 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_26_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_26_M2nCE0 (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_26_TCTA1 (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_26_M5nCE1 (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_26_M3nCE0 (AM_HAL_GPIO_FUNC(7)) + +#if defined (AM_PACKAGE_BGA) +#define AM_HAL_PIN_27_EXTHF (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_27_M1nCE4 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_27_TCTA1 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_27_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_27_M2SCL (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_OPENDRAIN) +#define AM_HAL_PIN_27_M2SCK (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_27_M2SCKLB (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_27_M2SCLLB (AM_HAL_GPIO_FUNC(7)) +#endif // defined (AM_PACKAGE_BGA) + +#define AM_HAL_PIN_28_I2S_WCLK (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_28_M1nCE5 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_28_TCTB1 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_28_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_28_M2WIR3 (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_3STATE) +#define AM_HAL_PIN_28_M2MOSI (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_28_M5nCE3 (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_28_SLWIR3LB (AM_HAL_GPIO_FUNC(7)) + +#define AM_HAL_PIN_29_ADCSE1 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_29_M1nCE6 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_29_TCTA2 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_29_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_29_UART0CTS (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_29_UART1CTS (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_29_M4nCE0 (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_29_PDM_DATA (AM_HAL_GPIO_FUNC(7) | AM_HAL_PIN_DIR_INPUT) + +#if defined (AM_PACKAGE_BGA) +#define AM_HAL_PIN_30_M1nCE7 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_30_TCTB2 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_30_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_30_UART0TX (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_30_UART1RTS (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_30_SWO (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_30_I2S_DAT (AM_HAL_GPIO_FUNC(7)) +#endif // defined (AM_PACKAGE_BGA) + +#if defined (AM_PACKAGE_BGA) +#define AM_HAL_PIN_31_ADCSE3 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_31_M0nCE4 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_31_TCTA3 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_31_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_31_UART0RX (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_31_TCTB1 (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#endif // defined (AM_PACKAGE_BGA) + +#if defined (AM_PACKAGE_BGA) +#define AM_HAL_PIN_32_ADCSE4 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_32_M0nCE5 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_32_TCTB3 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_32_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_32_TCTB1 (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#endif // defined (AM_PACKAGE_BGA) + +#if defined (AM_PACKAGE_BGA) +#define AM_HAL_PIN_33_ADCSE5 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_33_M0nCE6 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_33_32KHZ_XT (AM_HAL_GPIO_FUNC(2)) +#define AM_HAL_PIN_33_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_33_M3nCE7 (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_33_TCTB1 (AM_HAL_GPIO_FUNC(6) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_33_SWO (AM_HAL_GPIO_FUNC(7)) +#endif // defined (AM_PACKAGE_BGA) + +#if defined (AM_PACKAGE_BGA) +#define AM_HAL_PIN_34_ADCSE6 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_34_M0nCE7 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_34_M2nCE3 (AM_HAL_GPIO_FUNC(2)) +#define AM_HAL_PIN_34_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_34_CMPRF2 (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_34_M3nCE1 (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_34_M4nCE0 (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_34_M5nCE2 (AM_HAL_GPIO_FUNC(7)) +#endif // defined (AM_PACKAGE_BGA) + +#if defined (AM_PACKAGE_BGA) +#define AM_HAL_PIN_35_ADCSE7 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_35_M1nCE0 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_35_UART1TX (AM_HAL_GPIO_FUNC(2)) +#define AM_HAL_PIN_35_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_35_M4nCE6 (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_35_TCTA1 (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_35_UART0RTS (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_35_M3nCE2 (AM_HAL_GPIO_FUNC(7)) +#endif // defined (AM_PACKAGE_BGA) + +#if defined (AM_PACKAGE_BGA) +#define AM_HAL_PIN_36_TRIG1 (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_36_M1nCE1 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_36_UART1RX (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_36_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_36_32KHZ_XT (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_36_M2nCE0 (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_36_UART0CTS (AM_HAL_GPIO_FUNC(6) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_36_M3nCE3 (AM_HAL_GPIO_FUNC(7)) +#endif // defined (AM_PACKAGE_BGA) + +#if defined (AM_PACKAGE_BGA) +#define AM_HAL_PIN_37_TRIG2 (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_37_M1nCE2 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_37_UART0RTS (AM_HAL_GPIO_FUNC(2)) +#define AM_HAL_PIN_37_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_37_M3nCE4 (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_37_M4nCE1 (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_37_PDM_CLK (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_37_TCTA1 (AM_HAL_GPIO_FUNC(7) | AM_HAL_PIN_DIR_INPUT) +#endif // defined (AM_PACKAGE_BGA) + +#if defined (AM_PACKAGE_BGA) +#define AM_HAL_PIN_38_TRIG3 (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_38_M1nCE3 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_38_UART0CTS (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_38_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_38_M3WIR3 (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_3STATE) +#define AM_HAL_PIN_38_M3MOSI (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_38_M4nCE7 (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_38_SLWIR3LB (AM_HAL_GPIO_FUNC(7)) +#endif // defined (AM_PACKAGE_BGA) + +#define AM_HAL_PIN_39_UART0TX (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_39_UART1TX (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_39_CLKOUT (AM_HAL_GPIO_FUNC(2)) +#define AM_HAL_PIN_39_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_39_M4SCL (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_OPENDRAIN) +#define AM_HAL_PIN_39_M4SCK (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_39_M4SCKLB (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_39_M4SCLLB (AM_HAL_GPIO_FUNC(7)) + +#define AM_HAL_PIN_40_UART0RX (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_40_UART1RX (AM_HAL_GPIO_FUNC(1) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_40_TRIG0 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_40_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_40_M4SDA (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_OPENDRAIN) +#define AM_HAL_PIN_40_M4MISO (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_40_SLMISOLB (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_40_SLSDALB (AM_HAL_GPIO_FUNC(7)) + +#define AM_HAL_PIN_41_M2nCE1 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_41_CLKOUT (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_41_SWO (AM_HAL_GPIO_FUNC(2)) +#define AM_HAL_PIN_41_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_41_M3nCE5 (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_41_M5nCE7 (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_41_M4nCE2 (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_41_UART0RTS (AM_HAL_GPIO_FUNC(7)) +#define AM_HAL_PIN_41_PSOURCE (AM_HAL_GPIO_FUNC(3) | AM_HAL_PIN_DIR_OUTPUT | AM_HAL_GPIO_POWER) + +#if defined (AM_PACKAGE_BGA) +#define AM_HAL_PIN_42_M2nCE2 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_42_M0nCE0 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_42_TCTA0 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_42_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_42_M3SCL (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_OPENDRAIN) +#define AM_HAL_PIN_42_M3SCK (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_42_M3SCKLB (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_42_M3SCLLB (AM_HAL_GPIO_FUNC(7)) +#endif // defined (AM_PACKAGE_BGA) + +#if defined (AM_PACKAGE_BGA) +#define AM_HAL_PIN_43_M2nCE4 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_43_M0nCE1 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_43_TCTB0 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_43_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_43_M3SDA (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_OPENDRAIN) +#define AM_HAL_PIN_43_M3MISO (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_43_SLMISOLB (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_43_SLSDALB (AM_HAL_GPIO_FUNC(7)) +#endif // defined (AM_PACKAGE_BGA) + +#define AM_HAL_PIN_44_UART1RTS (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_44_M0nCE2 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_44_TCTA1 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_44_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_44_M4WIR3 (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_3STATE) +#define AM_HAL_PIN_44_M4MOSI (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_44_M5nCE6 (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_44_SLWIR3LB (AM_HAL_GPIO_FUNC(7)) + +#if defined (AM_PACKAGE_BGA) +#define AM_HAL_PIN_45_UART1CTS (AM_HAL_GPIO_FUNC(0) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_45_M0nCE3 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_45_TCTB1 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_45_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_45_M4nCE3 (AM_HAL_GPIO_FUNC(4)) +#define AM_HAL_PIN_45_M3nCE6 (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_45_M5nCE5 (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_45_TCTA1 (AM_HAL_GPIO_FUNC(7) | AM_HAL_PIN_DIR_INPUT) +#endif // defined (AM_PACKAGE_BGA) + +#if defined (AM_PACKAGE_BGA) +#define AM_HAL_PIN_46_32KHZ_XT (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_46_M0nCE4 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_46_TCTA2 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_46_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_46_TCTA1 (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_46_M5nCE4 (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_46_M4nCE4 (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_46_SWO (AM_HAL_GPIO_FUNC(7)) +#endif // defined (AM_PACKAGE_BGA) + +#define AM_HAL_PIN_47_M2nCE5 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_47_M0nCE5 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_47_TCTB2 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_47_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_47_M5WIR3 (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_3STATE) +#define AM_HAL_PIN_47_M5MOSI (AM_HAL_GPIO_FUNC(5)) +#define AM_HAL_PIN_47_M4nCE5 (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_47_SLWIR3LB (AM_HAL_GPIO_FUNC(7)) + +#define AM_HAL_PIN_48_M2nCE6 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_48_M0nCE6 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_48_TCTA3 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_48_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_48_M5SCL (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_OPENDRAIN) +#define AM_HAL_PIN_48_M5SCK (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_48_M5SCKLB (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_48_M5SCLLB (AM_HAL_GPIO_FUNC(7)) + +#define AM_HAL_PIN_49_M2nCE7 (AM_HAL_GPIO_FUNC(0)) +#define AM_HAL_PIN_49_M0nCE7 (AM_HAL_GPIO_FUNC(1)) +#define AM_HAL_PIN_49_TCTB3 (AM_HAL_GPIO_FUNC(2) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_49_GPIO (AM_HAL_GPIO_FUNC(3)) +#define AM_HAL_PIN_49_M5SDA (AM_HAL_GPIO_FUNC(4) | AM_HAL_PIN_DIR_OPENDRAIN) +#define AM_HAL_PIN_49_M5MISO (AM_HAL_GPIO_FUNC(5) | AM_HAL_PIN_DIR_INPUT) +#define AM_HAL_PIN_49_SLMISOLB (AM_HAL_GPIO_FUNC(6)) +#define AM_HAL_PIN_49_SLSDALB (AM_HAL_GPIO_FUNC(7)) + +#endif // AM_HAL_PIN_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_pwrctrl.c b/bsp/apollo2/libraries/drivers/hal/am_hal_pwrctrl.c new file mode 100644 index 0000000000..cc91eeb159 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_pwrctrl.c @@ -0,0 +1,558 @@ +//***************************************************************************** +// +// am_hal_pwrctrl.c +//! @file +//! +//! @brief Functions for enabling and disabling power domains. +//! +//! @addtogroup pwrctrl2 Power Control +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +// ONE_BIT - true iff value has exactly 1 bit set. +// +//***************************************************************************** +#define ONE_BIT(ui32Value) (ui32Value && !(ui32Value & (ui32Value - 1))) + +//***************************************************************************** +// +// Determine if this is an Apollo2 revision that requires additional handling +// of the BUCK to LDO transition when only the ADC is in use and going to +// deepsleep. +// +//***************************************************************************** +static bool +isRev_ADC(void) +{ + return AM_BFM(MCUCTRL, CHIPREV, REVMAJ) == AM_REG_MCUCTRL_CHIPREV_REVMAJ_B ? + true : false; +} + +//***************************************************************************** +// +//! @brief Enable power for a peripheral. +//! +//! @param ui32Peripheral - The peripheral to enable +//! +//! This function directly enables or disables power for the chosen peripheral. +//! +//! @note Unpowered peripherals may lose their configuration information. This +//! function does not save or restore peripheral configuration registers. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_pwrctrl_periph_enable(uint32_t ui32Peripheral) +{ + + am_hal_debug_assert_msg(ONE_BIT(ui32Peripheral), + "Cannot enable more than one peripheral at a time."); + + // + // Begin critical section. + // + AM_CRITICAL_BEGIN_ASM + + // + // Enable power control for the given device. + // + AM_REG(PWRCTRL, DEVICEEN) |= ui32Peripheral; + + // + // End Critical Section. + // + AM_CRITICAL_END_ASM + + // + // Wait for the power to stablize. Using a simple delay loop is more + // power efficient than a polling loop. + // + am_hal_flash_delay(AM_HAL_PWRCTRL_DEVICEEN_DELAYCYCLES / 3); + + // + // Quick check to guarantee we're good (should never be more than 1 read). + // + POLL_PWRSTATUS(ui32Peripheral); +} + +//***************************************************************************** +// +//! @brief Disable power for a peripheral. +//! +//! @param ui32Peripheral - The peripheral to disable +//! +//! This function directly disables or disables power for the chosen peripheral. +//! +//! @note Unpowered peripherals may lose their configuration information. This +//! function does not save or restore peripheral configuration registers. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_pwrctrl_periph_disable(uint32_t ui32Peripheral) +{ + + am_hal_debug_assert_msg(ONE_BIT(ui32Peripheral), + "Cannot enable more than one peripheral at a time."); + + // + // Begin critical section. + // + AM_CRITICAL_BEGIN_ASM + + // + // Disable power control for the given device. + // + AM_REG(PWRCTRL, DEVICEEN) &= ~ui32Peripheral; + + // + // End critical section. + // + AM_CRITICAL_END_ASM + + // + // Wait for the power to stablize + // + am_hal_flash_delay(AM_HAL_PWRCTRL_DEVICEDIS_DELAYCYCLES / 3); +} + +//***************************************************************************** +// +//! @brief Enable and disable power for memory devices (SRAM, flash, cache). +//! +//! @param ui32MemEn - The memory and amount to be enabled. +//! Must be one of the following: +//! AM_HAL_PWRCTRL_MEMEN_CACHE +//! AM_HAL_PWRCTRL_MEMEN_CACHE_DIS +//! AM_HAL_PWRCTRL_MEMEN_FLASH512K +//! AM_HAL_PWRCTRL_MEMEN_FLASH1M +//! AM_HAL_PWRCTRL_MEMEN_SRAM8K +//! AM_HAL_PWRCTRL_MEMEN_SRAM16K +//! AM_HAL_PWRCTRL_MEMEN_SRAM24K +//! AM_HAL_PWRCTRL_MEMEN_SRAM32K +//! AM_HAL_PWRCTRL_MEMEN_SRAM64K +//! AM_HAL_PWRCTRL_MEMEN_SRAM96K +//! AM_HAL_PWRCTRL_MEMEN_SRAM128K +//! AM_HAL_PWRCTRL_MEMEN_SRAM160K +//! AM_HAL_PWRCTRL_MEMEN_SRAM192K +//! AM_HAL_PWRCTRL_MEMEN_SRAM224K +//! AM_HAL_PWRCTRL_MEMEN_SRAM256K +//! AM_HAL_PWRCTRL_MEMEN_ALL (the default, power-up state) +//! +//! This function enables/disables power to provide only the given amount of +//! the type of memory specified. +//! +//! Only the type of memory specified is affected. Therefore separate calls +//! are required to affect power settings for FLASH, SRAM, or CACHE. +//! +//! Settings for zero SRAM or FLASH are not provided as device behavior under +//! either of those conditions is undefined. +//! +//! @note Unpowered memory devices may lose their configuration information. +//! This function does not save or restore peripheral configuration registers. +//! +//! @return None. +// +//***************************************************************************** +bool +am_hal_pwrctrl_memory_enable(uint32_t ui32MemEn) +{ + uint32_t ui32MemEnMask, ui32MemDisMask; + uint32_t ui32PwrStatEnMask, ui32PwrStatDisMask; + int32_t i32TOcnt; + + if ( ui32MemEn == AM_HAL_PWRCTRL_MEMEN_FLASH512K ) + { + ui32MemEnMask = AM_REG_PWRCTRL_MEMEN_FLASH0_EN; + ui32MemDisMask = AM_REG_PWRCTRL_MEMEN_FLASH1_EN; + ui32PwrStatEnMask = AM_REG_PWRCTRL_PWRONSTATUS_PD_FLAM0_M; + ui32PwrStatDisMask = AM_REG_PWRCTRL_PWRONSTATUS_PD_FLAM1_M; + } + else if ( ui32MemEn == AM_HAL_PWRCTRL_MEMEN_FLASH1M ) + { + ui32MemEnMask = AM_REG_PWRCTRL_MEMEN_FLASH0_EN | + AM_REG_PWRCTRL_MEMEN_FLASH1_EN; + ui32MemDisMask = 0; + ui32PwrStatEnMask = AM_REG_PWRCTRL_PWRONSTATUS_PD_FLAM0_M | + AM_REG_PWRCTRL_PWRONSTATUS_PD_FLAM1_M; + ui32PwrStatDisMask = 0; + } + else if ( ui32MemEn == AM_HAL_PWRCTRL_MEMEN_SRAM8K ) + { + ui32MemEnMask = AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM8K; + ui32MemDisMask = AM_REG_PWRCTRL_MEMEN_SRAMEN_ALL & + ~AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM8K; + ui32PwrStatEnMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_8K; + ui32PwrStatDisMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_ALL & + ~AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_8K; + } + else if ( ui32MemEn == AM_HAL_PWRCTRL_MEMEN_SRAM16K ) + { + ui32MemEnMask = AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM16K; + ui32MemDisMask = AM_REG_PWRCTRL_MEMEN_SRAMEN_ALL & + ~AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM16K; + ui32PwrStatEnMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_16K; + ui32PwrStatDisMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_ALL & + ~AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_16K; + } + else if ( ui32MemEn == AM_HAL_PWRCTRL_MEMEN_SRAM24K ) + { + ui32MemEnMask = AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP0_SRAM0 | + AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP0_SRAM1 | + AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP0_SRAM2; + ui32MemDisMask = AM_REG_PWRCTRL_MEMEN_SRAMEN_ALL & + ~(AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP0_SRAM0 | + AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP0_SRAM1 | + AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP0_SRAM2); + ui32PwrStatEnMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_24K; + ui32PwrStatDisMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_ALL & + ~AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_24K; + } + else if ( ui32MemEn == AM_HAL_PWRCTRL_MEMEN_SRAM32K ) + { + ui32MemEnMask = AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM32K; + ui32MemDisMask = AM_REG_PWRCTRL_MEMEN_SRAMEN_ALL & + ~AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM32K; + ui32PwrStatEnMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_32K; + ui32PwrStatDisMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_ALL & + ~AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_32K; + } + else if ( ui32MemEn == AM_HAL_PWRCTRL_MEMEN_SRAM64K ) + { + ui32MemEnMask = AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM64K; + ui32MemDisMask = AM_REG_PWRCTRL_MEMEN_SRAMEN_ALL & + ~AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM64K; + ui32PwrStatEnMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_64K; + ui32PwrStatDisMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_ALL & + ~AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_64K; + } + else if ( ui32MemEn == AM_HAL_PWRCTRL_MEMEN_SRAM96K ) + { + ui32MemEnMask = AM_HAL_PWRCTRL_MEMEN_SRAM96K; + ui32MemDisMask = AM_REG_PWRCTRL_MEMEN_SRAMEN_ALL & + ~AM_HAL_PWRCTRL_MEMEN_SRAM96K; + ui32PwrStatEnMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_96K; + ui32PwrStatDisMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_ALL & + ~AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_96K; + } + else if ( ui32MemEn == AM_HAL_PWRCTRL_MEMEN_SRAM128K ) + { + ui32MemEnMask = AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM128K; + ui32MemDisMask = AM_REG_PWRCTRL_MEMEN_SRAMEN_ALL & + ~AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM128K; + ui32PwrStatEnMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_128K; + ui32PwrStatDisMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_ALL & + ~AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_128K; + } + else if ( ui32MemEn == AM_HAL_PWRCTRL_MEMEN_SRAM160K ) + { + ui32MemEnMask = AM_HAL_PWRCTRL_MEMEN_SRAM160K; + ui32MemDisMask = AM_REG_PWRCTRL_MEMEN_SRAMEN_ALL & + ~AM_HAL_PWRCTRL_MEMEN_SRAM160K; + ui32PwrStatEnMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_160K; + ui32PwrStatDisMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_ALL & + ~AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_160K; + } + else if ( ui32MemEn == AM_HAL_PWRCTRL_MEMEN_SRAM192K ) + { + ui32MemEnMask = AM_HAL_PWRCTRL_MEMEN_SRAM192K; + ui32MemDisMask = AM_REG_PWRCTRL_MEMEN_SRAMEN_ALL & + ~AM_HAL_PWRCTRL_MEMEN_SRAM192K; + ui32PwrStatEnMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_192K; + ui32PwrStatDisMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_ALL & + ~AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_192K; + } + else if ( ui32MemEn == AM_HAL_PWRCTRL_MEMEN_SRAM224K ) + { + ui32MemEnMask = AM_HAL_PWRCTRL_MEMEN_SRAM224K; + ui32MemDisMask = AM_REG_PWRCTRL_MEMEN_SRAMEN_ALL & + ~AM_HAL_PWRCTRL_MEMEN_SRAM224K; + ui32PwrStatEnMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_224K; + ui32PwrStatDisMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_ALL & + ~AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_224K; + } + else if ( ui32MemEn == AM_HAL_PWRCTRL_MEMEN_SRAM256K ) + { + ui32MemEnMask = AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM256K; + ui32MemDisMask = AM_REG_PWRCTRL_MEMEN_SRAMEN_ALL & + ~AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM256K; + ui32PwrStatEnMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_256K; + ui32PwrStatDisMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_ALL & + ~AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_256K; + } + else if ( ui32MemEn == AM_HAL_PWRCTRL_MEMEN_CACHE ) + { + ui32MemEnMask = AM_REG_PWRCTRL_MEMEN_CACHEB0_EN | + AM_REG_PWRCTRL_MEMEN_CACHEB2_EN; + ui32MemDisMask = 0; + ui32PwrStatEnMask = AM_REG_PWRCTRL_PWRONSTATUS_PD_CACHEB2_M | + AM_REG_PWRCTRL_PWRONSTATUS_PD_CACHEB0_M; + ui32PwrStatDisMask = 0; + } + else if ( ui32MemEn == AM_HAL_PWRCTRL_MEMEN_CACHE_DIS ) + { + ui32MemEnMask = 0; + ui32MemDisMask = AM_REG_PWRCTRL_MEMEN_CACHEB0_EN | + AM_REG_PWRCTRL_MEMEN_CACHEB2_EN; + ui32PwrStatEnMask = 0; + ui32PwrStatDisMask = AM_REG_PWRCTRL_PWRONSTATUS_PD_CACHEB2_M | + AM_REG_PWRCTRL_PWRONSTATUS_PD_CACHEB0_M; + } + else if ( ui32MemEn == AM_HAL_PWRCTRL_MEMEN_ALL ) + { + ui32MemEnMask = AM_HAL_PWRCTRL_MEMEN_ALL; + ui32MemDisMask = 0; + ui32PwrStatEnMask = AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_ALL; + ui32PwrStatDisMask = 0; + } + else + { + return false; + } + + // + // Disable unneeded memory. If nothing to be disabled, skip to save time. + // + // Note that a deliberate disable step using a disable mask is taken here + // for 2 reasons: 1) To only affect the specified type of memory, and 2) + // To avoid inadvertently disabling any memory currently being depended on. + // + if ( ui32MemDisMask != 0 ) + { + AM_REG(PWRCTRL, MEMEN) &= ~ui32MemDisMask; + } + + // + // Enable the required memory. + // + if ( ui32MemEnMask != 0 ) + { + AM_REG(PWRCTRL, MEMEN) |= ui32MemEnMask; + } + + // + // Wait for the power to be turned on. + // Apollo2 note - these loops typically end up taking 1 iteration. + // + i32TOcnt = 200; + if ( ui32PwrStatDisMask ) + { + while ( --i32TOcnt && + ( AM_REG(PWRCTRL, PWRONSTATUS) & ui32PwrStatDisMask ) ); + } + + if ( i32TOcnt <= 0 ) + { + return false; + } + + i32TOcnt = 200; + if ( ui32PwrStatEnMask ) + { + while ( --i32TOcnt && + (( AM_REG(PWRCTRL, PWRONSTATUS) & ui32PwrStatEnMask ) + != ui32PwrStatEnMask) ); + } + if ( i32TOcnt <= 0 ) + { + return false; + } + + return true; +} + +//***************************************************************************** +// +//! @brief Initialize the core and memory buck converters. +//! +//! This function is intended to be used for first time core and memory buck +//! converters initialization. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_pwrctrl_bucks_init(void) +{ + am_hal_pwrctrl_bucks_enable(); + + while ( ( AM_REG(PWRCTRL, POWERSTATUS) & + ( AM_REG_PWRCTRL_POWERSTATUS_COREBUCKON_M | + AM_REG_PWRCTRL_POWERSTATUS_MEMBUCKON_M ) ) != + ( AM_REG_PWRCTRL_POWERSTATUS_COREBUCKON_M | + AM_REG_PWRCTRL_POWERSTATUS_MEMBUCKON_M ) ); + + // + // Additional delay to make sure BUCKs are initialized. + // + am_hal_flash_delay(200 / 3); +} + +//***************************************************************************** +// +//! @brief Enable the core and memory buck converters. +//! +//! This function enables the core and memory buck converters. +//! +//! @return None +// +//***************************************************************************** +#define LDO_TRIM_REG_ADDR (0x50023004) +#define BUCK_TRIM_REG_ADDR (0x50023000) + +void +am_hal_pwrctrl_bucks_enable(void) +{ + // + // Check to see if the bucks are already on. If so, we can just return. + // + if ( AM_BFR(PWRCTRL, POWERSTATUS, COREBUCKON) && + AM_BFR(PWRCTRL, POWERSTATUS, MEMBUCKON) ) + { + return; + } + + // + // Enable BUCK power up + // + AM_BFW(PWRCTRL, SUPPLYSRC, COREBUCKEN, 1); + AM_BFW(PWRCTRL, SUPPLYSRC, MEMBUCKEN, 1); + + // + // Make sure bucks are ready. + // + while ( ( AM_REG(PWRCTRL, POWERSTATUS) & + ( AM_REG_PWRCTRL_POWERSTATUS_COREBUCKON_M | + AM_REG_PWRCTRL_POWERSTATUS_MEMBUCKON_M ) ) != + ( AM_REG_PWRCTRL_POWERSTATUS_COREBUCKON_M | + AM_REG_PWRCTRL_POWERSTATUS_MEMBUCKON_M ) ); +} + +//***************************************************************************** +// +//! @brief Disable the core and memory buck converters. +//! +//! This function disables the core and memory buck converters. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_pwrctrl_bucks_disable(void) +{ + // + // Check to see if the bucks are already off. If so, we can just return. + // + if ( AM_BFR(PWRCTRL, POWERSTATUS, COREBUCKON) == 0 && + AM_BFR(PWRCTRL, POWERSTATUS, MEMBUCKON) == 0) + { + return; + } + + // + // Handle the special case if only the ADC is powered. + // + if ( isRev_ADC() && + (AM_REG(PWRCTRL, DEVICEEN) == AM_REG_PWRCTRL_DEVICEEN_ADC_EN) ) + { + // + // Set SUPPLYSRC to handle this case + // + AM_REG(PWRCTRL, SUPPLYSRC) &= + (AM_REG_PWRCTRL_SUPPLYSRC_SWITCH_LDO_IN_SLEEP_EN | + AM_REG_PWRCTRL_SUPPLYSRC_MEMBUCKEN_EN); + } + else + { + // + // Power them down + // + AM_BFW(PWRCTRL, SUPPLYSRC, COREBUCKEN, 0); + AM_BFW(PWRCTRL, SUPPLYSRC, MEMBUCKEN, 0); + } + + // + // Wait until BUCKs are disabled. + // + am_hal_flash_delay(AM_HAL_PWRCTRL_BUCKDIS_DELAYCYCLES / 3); +} + +//***************************************************************************** +// +//! @brief Misc low power initializations. +//! +//! This function performs low power initializations that aren't specifically +//! handled elsewhere. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_pwrctrl_low_power_init(void) +{ + // + // For lowest power, we enable clock gating for all SRAM configuration. + // + AM_REG(PWRCTRL, SRAMCTRL) |= + AM_REG_PWRCTRL_SRAMCTRL_SRAM_MASTER_CLKGATE_EN | + AM_REG_PWRCTRL_SRAMCTRL_SRAM_CLKGATE_EN | + AM_REG_PWRCTRL_SRAMCTRL_SRAM_LIGHT_SLEEP_DIS; + + // + // For lowest deep sleep power, make sure we stay in BUCK mode. + // + AM_REG(PWRCTRL, SUPPLYSRC) &= + ~AM_REG_PWRCTRL_SUPPLYSRC_SWITCH_LDO_IN_SLEEP_M; +} + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_pwrctrl.h b/bsp/apollo2/libraries/drivers/hal/am_hal_pwrctrl.h new file mode 100644 index 0000000000..bc9adabf84 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_pwrctrl.h @@ -0,0 +1,342 @@ +//***************************************************************************** +// +// am_hal_pwrctrl.h +//! @file +//! +//! @brief Functions for enabling and disabling power domains. +//! +//! @addtogroup pwrctrl2 Power Control +//! @ingroup apollo2hal +//! @{ + +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#ifndef AM_HAL_PWRCTRL_H +#define AM_HAL_PWRCTRL_H + +//***************************************************************************** +// +// Peripheral enable bits for am_hal_pwrctrl_periph_enable/disable() +// +//***************************************************************************** +#define AM_HAL_PWRCTRL_ADC AM_REG_PWRCTRL_DEVICEEN_ADC_EN +#define AM_HAL_PWRCTRL_IOM0 AM_REG_PWRCTRL_DEVICEEN_IO_MASTER0_EN +#define AM_HAL_PWRCTRL_IOM1 AM_REG_PWRCTRL_DEVICEEN_IO_MASTER1_EN +#define AM_HAL_PWRCTRL_IOM2 AM_REG_PWRCTRL_DEVICEEN_IO_MASTER2_EN +#define AM_HAL_PWRCTRL_IOM3 AM_REG_PWRCTRL_DEVICEEN_IO_MASTER3_EN +#define AM_HAL_PWRCTRL_IOM4 AM_REG_PWRCTRL_DEVICEEN_IO_MASTER4_EN +#define AM_HAL_PWRCTRL_IOM5 AM_REG_PWRCTRL_DEVICEEN_IO_MASTER5_EN +#define AM_HAL_PWRCTRL_IOS AM_REG_PWRCTRL_DEVICEEN_IO_SLAVE_EN +#define AM_HAL_PWRCTRL_PDM AM_REG_PWRCTRL_DEVICEEN_PDM_EN +#define AM_HAL_PWRCTRL_UART0 AM_REG_PWRCTRL_DEVICEEN_UART0_EN +#define AM_HAL_PWRCTRL_UART1 AM_REG_PWRCTRL_DEVICEEN_UART1_EN + +//***************************************************************************** +// +// Macro to set the appropriate IOM peripheral when using +// am_hal_pwrctrl_periph_enable()/disable(). +// For Apollo2, the module argument must resolve to be a value from 0-5. +// +//***************************************************************************** +#define AM_HAL_PWRCTRL_IOM(module) \ + (AM_REG_PWRCTRL_DEVICEEN_IO_MASTER0_EN << module) + +//***************************************************************************** +// +// Macro to set the appropriate UART peripheral when using +// am_hal_pwrctrl_periph_enable()/disable(). +// For Apollo2, the module argument must resolve to be a value from 0-1. +// +//***************************************************************************** +#define AM_HAL_PWRCTRL_UART(module) \ + (AM_REG_PWRCTRL_DEVICEEN_UART0_EN << module) + + +//***************************************************************************** +// +// Memory enable values for am_hal_pwrctrl_memory_enable() +// +//***************************************************************************** +#define AM_HAL_PWRCTRL_MEMEN_SRAM8K AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM8K +#define AM_HAL_PWRCTRL_MEMEN_SRAM16K AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM16K +#define AM_HAL_PWRCTRL_MEMEN_SRAM24K (AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM16K | \ + AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP0_SRAM2) +#define AM_HAL_PWRCTRL_MEMEN_SRAM32K AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM32K +#define AM_HAL_PWRCTRL_MEMEN_SRAM64K AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM64K +#define AM_HAL_PWRCTRL_MEMEN_SRAM96K \ + (AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM64K | \ + AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP2) +#define AM_HAL_PWRCTRL_MEMEN_SRAM128K AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM128K +#define AM_HAL_PWRCTRL_MEMEN_SRAM160K \ + (AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM128K | \ + AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP4) +#define AM_HAL_PWRCTRL_MEMEN_SRAM192K \ + (AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM128K | \ + AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP4 | \ + AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP5) +#define AM_HAL_PWRCTRL_MEMEN_SRAM224K \ + (AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM128K | \ + AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP4 | \ + AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP5 | \ + AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP6) +#define AM_HAL_PWRCTRL_MEMEN_SRAM256K AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM256K + +#define AM_HAL_PWRCTRL_MEMEN_FLASH512K AM_REG_PWRCTRL_MEMEN_FLASH0_EN +#define AM_HAL_PWRCTRL_MEMEN_FLASH1M \ + (AM_REG_PWRCTRL_MEMEN_FLASH0_EN | \ + AM_REG_PWRCTRL_MEMEN_FLASH1_EN) +#define AM_HAL_PWRCTRL_MEMEN_CACHE \ + (AM_REG_PWRCTRL_MEMEN_CACHEB0_EN | \ + AM_REG_PWRCTRL_MEMEN_CACHEB2_EN) +#define AM_HAL_PWRCTRL_MEMEN_CACHE_DIS \ + ~(AM_REG_PWRCTRL_MEMEN_CACHEB0_EN | \ + AM_REG_PWRCTRL_MEMEN_CACHEB2_EN) + +// +// Power up all available memory devices (this is the default power up state) +// +#define AM_HAL_PWRCTRL_MEMEN_ALL \ + (AM_REG_PWRCTRL_MEMEN_SRAMEN_ALL | \ + AM_REG_PWRCTRL_MEMEN_FLASH0_EN | \ + AM_REG_PWRCTRL_MEMEN_FLASH1_EN | \ + AM_REG_PWRCTRL_MEMEN_CACHEB0_EN | \ + AM_REG_PWRCTRL_MEMEN_CACHEB2_EN) + +//***************************************************************************** +// +// Peripheral power enable and disable delays +// The delay counts are based on an internal clock that runs at half of +// HFRC. Therefore, we need to double the delay cycles. +// +//***************************************************************************** +#define AM_HAL_PWRCTRL_DEVICEEN_DELAYCYCLES (22 * 2) +#define AM_HAL_PWRCTRL_DEVICEDIS_DELAYCYCLES (22 * 2) + +// +// Use the following only when enabling after sleep (not during initialization). +// +#define AM_HAL_PWRCTRL_BUCKEN_DELAYCYCLES (0 * 2) +#define AM_HAL_PWRCTRL_BUCKDIS_DELAYCYCLES (15 * 2) + +//***************************************************************************** +// +// Peripheral PWRONSTATUS groupings. +// +//***************************************************************************** +// +// Group DEVICEEN bits (per PWRONSTATUS groupings). +// +#define AM_HAL_PWRCTRL_DEVICEEN_IOM_0_2 \ + (AM_REG_PWRCTRL_DEVICEEN_IO_MASTER0_EN | \ + AM_REG_PWRCTRL_DEVICEEN_IO_MASTER1_EN | \ + AM_REG_PWRCTRL_DEVICEEN_IO_MASTER2_EN ) + +#define AM_HAL_PWRCTRL_DEVICEEN_IOM_3_5 \ + (AM_REG_PWRCTRL_DEVICEEN_IO_MASTER3_EN | \ + AM_REG_PWRCTRL_DEVICEEN_IO_MASTER4_EN | \ + AM_REG_PWRCTRL_DEVICEEN_IO_MASTER5_EN ) + +#define AM_HAL_PWRCTRL_DEVICEEN_IOS_UARTS \ + (AM_REG_PWRCTRL_DEVICEEN_UART0_EN | \ + AM_REG_PWRCTRL_DEVICEEN_UART1_EN | \ + AM_REG_PWRCTRL_DEVICEEN_IO_SLAVE_EN ) + +#define AM_HAL_PWRCTRL_DEVICEEN_ADC AM_REG_PWRCTRL_DEVICEEN_ADC_EN +#define AM_HAL_PWRCTRL_DEVICEEN_PDM AM_REG_PWRCTRL_DEVICEEN_PDM_EN + +// +// Map PWRONSTATUS bits to peripheral groupings. +// +#define AM_HAL_PWRCTRL_PWRONSTATUS_IOS_UARTS AM_REG_PWRCTRL_PWRONSTATUS_PDA_M +#define AM_HAL_PWRCTRL_PWRONSTATUS_IOM_3_5 AM_REG_PWRCTRL_PWRONSTATUS_PDC_M +#define AM_HAL_PWRCTRL_PWRONSTATUS_IOM_0_2 AM_REG_PWRCTRL_PWRONSTATUS_PDB_M +#define AM_HAL_PWRCTRL_PWRONSTATUS_ADC AM_REG_PWRCTRL_PWRONSTATUS_PDADC_M +#define AM_HAL_PWRCTRL_PWRONSTATUS_PDM AM_REG_PWRCTRL_PWRONSTATUS_PD_PDM_M + +#define POLL_PWRSTATUS(ui32Peripheral) \ + if ( 1 ) \ + { \ + uint32_t ui32PwrOnStat; \ + if ( ui32Peripheral & AM_HAL_PWRCTRL_DEVICEEN_IOM_0_2 ) \ + { \ + ui32PwrOnStat = AM_HAL_PWRCTRL_PWRONSTATUS_IOM_0_2; \ + } \ + else if ( ui32Peripheral & AM_HAL_PWRCTRL_DEVICEEN_IOM_3_5 ) \ + { \ + ui32PwrOnStat = AM_HAL_PWRCTRL_PWRONSTATUS_IOM_3_5; \ + } \ + else if ( ui32Peripheral & AM_HAL_PWRCTRL_DEVICEEN_IOS_UARTS ) \ + { \ + ui32PwrOnStat = AM_HAL_PWRCTRL_PWRONSTATUS_IOS_UARTS; \ + } \ + else if ( ui32Peripheral & AM_HAL_PWRCTRL_DEVICEEN_ADC ) \ + { \ + ui32PwrOnStat = AM_HAL_PWRCTRL_PWRONSTATUS_ADC; \ + } \ + else if ( ui32Peripheral & AM_HAL_PWRCTRL_DEVICEEN_PDM ) \ + { \ + ui32PwrOnStat = AM_HAL_PWRCTRL_PWRONSTATUS_PDM; \ + } \ + else \ + { \ + ui32PwrOnStat = 0xFFFFFFFF; \ + } \ + \ + /* */ \ + /* Wait for the power control setting to take effect. */ \ + /* */ \ + while ( !(AM_REG(PWRCTRL, PWRONSTATUS) & ui32PwrOnStat) ); \ + } + +//***************************************************************************** +// +// Memory PWRONSTATUS enable values for am_hal_pwrctrl_memory_enable() +// +//***************************************************************************** +#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_8K \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM0_M + +#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_16K \ + (AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM1_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM0_M) + +#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_24K \ + (AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM2_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM1_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM0_M) + +#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_32K \ + (AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM3_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM2_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM1_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM0_M) + +#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_64K \ + (AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP1_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM3_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM2_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM1_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM0_M) + +#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_96K \ + (AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP2_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP1_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM3_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM2_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM1_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM0_M) + +#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_128K \ + (AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP3_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP2_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP1_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM3_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM2_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM1_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM0_M) + +#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_160K \ + (AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP4_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP3_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP2_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP1_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM3_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM2_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM1_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM0_M) + +#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_192K \ + (AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP5_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP4_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP3_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP2_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP1_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM3_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM2_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM1_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM0_M) + +#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_224K \ + (AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP6_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP5_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP4_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP3_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP2_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP1_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM3_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM2_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM1_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM0_M) + +#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_256K \ + (AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP7_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP6_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP5_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP4_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP3_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP2_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP1_SRAM_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM3_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM2_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM1_M | \ + AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM0_M) + +#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_ALL \ + AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_256K + +//***************************************************************************** +// +// Function prototypes +// +//***************************************************************************** +extern void am_hal_pwrctrl_periph_enable(uint32_t ui32Peripheral); +extern void am_hal_pwrctrl_periph_disable(uint32_t ui32Peripheral); +extern bool am_hal_pwrctrl_memory_enable(uint32_t ui32MemEn); +extern void am_hal_pwrctrl_bucks_init(void); +extern void am_hal_pwrctrl_bucks_enable(void); +extern void am_hal_pwrctrl_bucks_disable(void); +extern void am_hal_pwrctrl_low_power_init(void); + +#endif // AM_HAL_PWRCTRL_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_queue.c b/bsp/apollo2/libraries/drivers/hal/am_hal_queue.c new file mode 100644 index 0000000000..66a9846c29 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_queue.c @@ -0,0 +1,286 @@ +//***************************************************************************** +// +// am_hal_queue.c +//! @file +//! +//! @brief Functions for implementing a queue system. +//! +//! @addtogroup Miscellaneous2 Software Features (MISC) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +//! @brief Initializes a queue. +//! +//! @param psQueue - Pointer to a queue structure. +//! @param pvData - Pointer to a memory location to be used for data storage. +//! @param ui32ItemSize - Number of bytes per item in the queue. +//! @param ui32ArraySize - Number of bytes in the data array. +//! +//! This function initializes the members of a queue structure and attaches it +//! to an array of memory that it can use for storage. This function should be +//! called before the queue is used. +//! +//! In this example, we are creating a queue that can hold 1024 32-bit +//! integers. The integers themselves will be stored in the array named +//! pui32WorkingSpace, while information about the queue itself will be stored +//! in sDataQueue. +//! +//! @note The caller should not modify any of the members of am_hal_queue_t +//! structures. The queue API will handle these members in a thread-safe way. +//! +//! @note The queue will remember what size data is in it. Other queue API +//! functions will perform transfers in units of "items" where one "item" is +//! the number of bytes you specify in the \e ui32ItemSize argument upon +//! initialization. +//! +//! Example usage: +//! +//! @code +//! +//! // +//! // Declare a queue structure and an array of bytes we can use to store +//! // data. +//! // +//! am_hal_queue_t sDataQueue; +//! uint32_t pui32WorkingSpace[1024]; +//! +//! // +//! // Attach the queue structure to the working memory. +//! // +//! am_hal_queue_init(&sDataQueue, pui8WorkingSpace, sizeof(uint32_t) +//! sizeof(pui32WorkingSpace)); +//! +//! @endcode +//! +//! The am_hal_queue_from_array macro is a convenient shorthand for this +//! operation. The code below does the same thing as the code above. +//! +//! @code +//! +//! // +//! // Declare a queue structure and an array of bytes we can use to store +//! // data. +//! // +//! am_hal_queue_t sDataQueue; +//! uint32_t pui32WorkingSpace[1024]; +//! +//! // +//! // Attach the queue structure to the working memory. +//! // +//! am_hal_queue_from_array(&sDataQueue, pui8WorkingSpace); +//! +//! @endcode +// +//***************************************************************************** +void +am_hal_queue_init(am_hal_queue_t *psQueue, void *pvData, uint32_t ui32ItemSize, + uint32_t ui32ArraySize) +{ + psQueue->ui32WriteIndex = 0; + psQueue->ui32ReadIndex = 0; + psQueue->ui32Length = 0; + psQueue->ui32Capacity = ui32ArraySize; + psQueue->ui32ItemSize = ui32ItemSize; + psQueue->pui8Data = (uint8_t *) pvData; +} + +//***************************************************************************** +// +//! @brief Adds an item to the Queue +//! +//! @param psQueue - Pointer to a queue structure. +//! @param pvSource - Pointer to the data to be added. +//! @param ui32NumItems - Number of items to be added. +//! +//! This function will copy the data pointed to by pvSource into the queue. The +//! \e ui32NumItems term specifies the number of items to be copied from \e +//! pvSource. The size of an "item" depends on how the queue was initialized. +//! Please see am_hal_queue_init() for more information on this. +//! +//! @return true if the add operation was successful, or false if the queue +//! didn't have enough space. +// +//***************************************************************************** +bool +am_hal_queue_item_add(am_hal_queue_t *psQueue, const void *pvSource, uint32_t ui32NumItems) +{ + uint32_t i; + uint8_t *pui8Source; + uint32_t ui32Bytes = ui32NumItems * psQueue->ui32ItemSize; + bool bSuccess = false; + uint32_t ui32Primask; + + pui8Source = (uint8_t *) pvSource; + + ui32Primask = am_hal_interrupt_master_disable(); + + // + // Check to make sure that the buffer isn't already full + // + if ( am_hal_queue_space_left(psQueue) >= ui32Bytes ) + { + // + // Loop over the bytes in the source array. + // + for ( i = 0; i < ui32Bytes; i++ ) + { + // + // Write the value to the buffer. + // + psQueue->pui8Data[psQueue->ui32WriteIndex] = pui8Source[i]; + + // + // Advance the write index, making sure to wrap if necessary. + // + psQueue->ui32WriteIndex = ((psQueue->ui32WriteIndex + 1) % + psQueue->ui32Capacity); + } + + // + // Update the length value appropriately. + // + psQueue->ui32Length += ui32Bytes; + + // + // Report a success. + // + bSuccess = true; + } + else + { + // + // The buffer can't fit the amount of data requested. Return a + // failure. + // + bSuccess = false; + } + + am_hal_interrupt_master_set(ui32Primask); + + return bSuccess; +} + +//***************************************************************************** +// +//! @brief Removes an item from the Queue +//! +//! @param psQueue - Pointer to a queue structure. +//! @param pvDest - Pointer to the data to be added. +//! @param ui32NumItems - Number of items to be added. +//! +//! This function will copy the data from the queue into the memory pointed to +//! by pvDest. The \e ui32NumItems term specifies the number of items to be +//! copied from the queue. The size of an "item" depends on how the queue was +//! initialized. Please see am_hal_queue_init() for more information on this. +//! +//! @return true if we were able to pull the requested number of items from the +//! queue, or false if the queue didn't have that many items to pull. +// +//***************************************************************************** +bool +am_hal_queue_item_get(am_hal_queue_t *psQueue, void *pvDest, uint32_t ui32NumItems) +{ + uint32_t i; + uint8_t *pui8Dest; + uint32_t ui32Bytes = ui32NumItems * psQueue->ui32ItemSize; + bool bSuccess = false; + uint32_t ui32Primask; + + pui8Dest = (uint8_t *) pvDest; + + ui32Primask = am_hal_interrupt_master_disable(); + + // + // Check to make sure that the buffer isn't empty + // + if ( am_hal_queue_data_left(psQueue) >= ui32Bytes ) + { + // + // Loop over the bytes in the destination array. + // + for ( i = 0; i < ui32Bytes; i++ ) + { + // + // Grab the next value from the buffer. + // + pui8Dest[i] = psQueue->pui8Data[psQueue->ui32ReadIndex]; + + // + // Advance the read index, wrapping if needed. + // + psQueue->ui32ReadIndex = ((psQueue->ui32ReadIndex + 1) % + psQueue->ui32Capacity); + } + + // + // Adjust the length value to reflect the change. + // + psQueue->ui32Length -= ui32Bytes; + + // + // Report a success. + // + bSuccess = true; + } + else + { + // + // If the buffer didn't have enough data, just return false. + // + bSuccess = false; + } + + am_hal_interrupt_master_set(ui32Primask); + + return bSuccess; +} + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_queue.h b/bsp/apollo2/libraries/drivers/hal/am_hal_queue.h new file mode 100644 index 0000000000..11e8ace90a --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_queue.h @@ -0,0 +1,123 @@ +//***************************************************************************** +// +// am_hal_queue.h +//! @file +//! +//! @brief Functions for implementing a queue system. +//! +//! @addtogroup Miscellaneous2 Software Features (MISC) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_QUEUE_H +#define AM_HAL_QUEUE_H + +//***************************************************************************** +// +//! @brief A data structure that will operate as a queue. +//! +//! This data structure holds information necessary for operating a thread-safe +//! queue. When declaring a structure of type am_hal_queue_t, you will also need +//! to provide some working memory for the queue to use. For more information on +//! setting up and using the am_hal_queue_t structure, please see the +//! documentation for am_hal_queue_init(). +// +//***************************************************************************** +typedef struct +{ + uint32_t ui32WriteIndex; + uint32_t ui32ReadIndex; + uint32_t ui32Length; + uint32_t ui32Capacity; + uint32_t ui32ItemSize; + uint8_t *pui8Data; +} +am_hal_queue_t; + +//***************************************************************************** +// +// Function-like macros. +// +//***************************************************************************** +#define am_hal_queue_empty(psQueue) \ + ((psQueue)->ui32Length == 0) + +#define am_hal_queue_full(psQueue) \ + ((psQueue)->ui32Length == (psQueue)->ui32Capacity) + +#define am_hal_queue_space_left(psQueue) \ + ((psQueue)->ui32Capacity - (psQueue)->ui32Length) + +#define am_hal_queue_data_left(psQueue) \ + ((psQueue)->ui32Length) + +//***************************************************************************** +// +// Use this to make sure you get the size parameters right. +// +//***************************************************************************** +#define am_hal_queue_from_array(queue, array) \ + am_hal_queue_init((queue), (array), sizeof((array)[0]), sizeof(array)) + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// External function definitions. +// +//***************************************************************************** +extern void am_hal_queue_init(am_hal_queue_t *psQueue, void *pvData, uint32_t ui32ItemSize, uint32_t ui32ArraySize); +extern bool am_hal_queue_item_add(am_hal_queue_t *psQueue, const void *pvSource, uint32_t ui32NumItems); +extern bool am_hal_queue_item_get(am_hal_queue_t *psQueue, void *pvDest, uint32_t ui32NumItems); + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_QUEUE_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_reset.c b/bsp/apollo2/libraries/drivers/hal/am_hal_reset.c new file mode 100644 index 0000000000..86d5cf10b7 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_reset.c @@ -0,0 +1,160 @@ +//***************************************************************************** +// +// am_hal_reset.c +//! @file +//! +//! @brief Hardware abstraction layer for the Reset Generator module. +//! +//! @addtogroup rstgen2 Reset Generator (RSTGEN) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +//! @brief Configure the Reset Generator. +//! +//! @param ui32Config - Or together the supplied macros to enable +//! configurations to obtain the desired reset generator settings. +//! +//! This function will set the reset generator's configuration register based on +//! the user's desired settings listed in the supplied arugment. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_reset_init(uint32_t ui32Config) +{ + // + // Write the configuration to the reset generator + // + AM_REG(RSTGEN, CFG) = ui32Config; +} + +//***************************************************************************** +// +//! @brief Issue a POR (Apollo's last stage interrupt). +//! +//! This function will issue a POR reset. +//! The Apollo chip has numerous stages of reset. POR is the last and is also +//! the reset invoked by the chip's reset pin, the watchdog timer, the AIRCR +//! reset, and the SWD debugger requested interrupt. +//! +//! The Debug Access Port in the M4 is not cleared by this reset. +//! +//! @return None. +// +//***************************************************************************** +void am_hal_reset_por(void) +{ + // + // Write the POR key to the software POR register. + // + AM_REG(RSTGEN, SWPOR) = + AM_REG_RSTGEN_SWPOR_SWPORKEY(AM_REG_RSTGEN_SWPOR_SWPORKEY_KEYVALUE); +} + +//***************************************************************************** +// +//! @brief Issue a POI (Apollo's second stage interrupt). +//! +//! This function will issue a POI reset. +//! The Apollo chip has numerous stages of reset. POI is the second stage. +//! A few modules are reset by POI that are not reset by POR, notably POI +//! causes the shadow registers to be reloaded from the OTP. A full power +//! cycle or POI should be used after writing new flash, debug or SRAM +//! protection bits into the OTP for these protections to take effect. +//! +//! The Debug Access Port in the M4 is not cleared by this reset. +//! +//! @return None. +// +//***************************************************************************** +void am_hal_reset_poi(void) +{ + // + // Write the POI key to the software POI register. + // + AM_REG(RSTGEN, SWPOI) = + AM_REG_RSTGEN_SWPOI_SWPOIKEY(AM_REG_RSTGEN_SWPOI_SWPOIKEY_KEYVALUE); +} + +//***************************************************************************** +// +//! @brief Retrieve the status bits from the reset generator. +//! +//! This function will get the status bits from the reset generator. +//! These bits are sticky and show the accumulation of reset types that the +//! Apollo chip has experienced since power on. One should clear these out +//! after reading them. +//! +//! @return None. +// +//***************************************************************************** +uint32_t am_hal_reset_status_get(void) +{ + // + // Retrieve the reset generator status bits + // + return AM_REG(RSTGEN, STAT); +} + +//***************************************************************************** +// +//! @brief Clear ALL of the status bits in the reset generator. +//! +//! This function will clear all status bits in the reset generator status. +//! +//! @return None. +// +//***************************************************************************** +void am_hal_reset_status_clear(void) +{ + AM_REG(RSTGEN, CLRSTAT) = AM_REG_RSTGEN_CLRSTAT_CLRSTAT(1); +} + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_reset.h b/bsp/apollo2/libraries/drivers/hal/am_hal_reset.h new file mode 100644 index 0000000000..a3273dad10 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_reset.h @@ -0,0 +1,119 @@ +//***************************************************************************** +// +// am_hal_reset.h +//! @file +//! +//! @brief Hardware abstraction layer for the Reset Generator module. +//! +//! @addtogroup wdt2 Watchdog Timer (RSTGEN) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_RSTGEN_H +#define AM_HAL_RSTGEN_H + +//***************************************************************************** +// +//! @name Reset Generator Configuration +//! @brief These macros may be used to set the reset generator's configuration. +//! @{ +// +//***************************************************************************** +#define AM_HAL_RESET_CFG_WDT_RESET_ENABLE (AM_REG_RSTGEN_CFG_WDREN(1)) +// Brown out high (2.1v) reset enable. +#define AM_HAL_RESET_CFG_BOD_HIGH_RESET_ENABLE (AM_REG_RSTGEN_CFG_BODHREN(1)) +//! @} + +//***************************************************************************** +// +//! @name Reset Generator Status Bit Masks +//! @brief These macros may be used to determine which type(s) of resets have +//! been seen. +//! @{ +// +//***************************************************************************** +// Reset was initiated by a Watchdog Timer Reset. +#define AM_HAL_RESET_STAT_WDT (AM_REG_RSTGEN_STAT_WDRSTAT_M) + +// Reset was a initiated by Debugger Reset. +#define AM_HAL_RESET_STAT_DEBUG (AM_REG_RSTGEN_STAT_DBGRSTAT_M) + +// Reset was a initiated by Software POI Reset. +#define AM_HAL_RESET_STAT_POI (AM_REG_RSTGEN_STAT_POIRSTAT_M) + +// Reset was a initiated by Software POR or AIRCR Reset. +#define AM_HAL_RESET_STAT_SOFTWARE (AM_REG_RSTGEN_STAT_SWRSTAT_M) + +// Reset was initiated by a Brown-Out Reset. +#define AM_HAL_RESET_STAT_BOD (AM_REG_RSTGEN_STAT_BORSTAT_M) + +// Reset was initiated by a Power Cycle +#define AM_HAL_RESET_STAT_POWER_CYCLE (AM_REG_RSTGEN_STAT_PORSTAT_M) + +// Reset was initiated by an External Reset. +#define AM_HAL_RESET_STAT_EXTERNAL (AM_REG_RSTGEN_STAT_EXRSTAT_M) +//! @} + +#ifdef __cplusplus +extern "C" +{ +#endif +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern void am_hal_reset_init(uint32_t ui32Config); +extern void am_hal_reset_por(void); +extern void am_hal_reset_poi(void); +extern uint32_t am_hal_reset_status_get(void); +extern void am_hal_reset_status_clear(void); + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_RSTGEN_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_rtc.c b/bsp/apollo2/libraries/drivers/hal/am_hal_rtc.c new file mode 100644 index 0000000000..4630d5a117 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_rtc.c @@ -0,0 +1,678 @@ +//***************************************************************************** +// +// am_hal_rtc.c +//! @file +//! +//! @brief Functions for interfacing with the Real-Time Clock (RTC). +//! +//! @addtogroup rtc2 Real-Time Clock (RTC) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +// Converts a Binary Coded Decimal (BCD) byte to its Decimal form. +// +//***************************************************************************** +static uint8_t +bcd_to_dec(uint8_t ui8BCDByte) +{ + return (((ui8BCDByte & 0xF0) >> 4) * 10) + (ui8BCDByte & 0x0F); +} + +//***************************************************************************** +// +// Converts a Decimal byte to its Binary Coded Decimal (BCD) form. +// +//***************************************************************************** +static uint8_t +dec_to_bcd(uint8_t ui8DecimalByte) +{ + return (((ui8DecimalByte / 10) << 4) | (ui8DecimalByte % 10)); +} + +//***************************************************************************** +// +//! @brief Selects the clock source for the RTC. +//! +//! @param ui32OSC the clock source for the RTC. +//! +//! This function selects the clock source for the RTC. +//! +//! Valid values for ui32OSC are: +//! +//! AM_HAL_RTC_OSC_LFRC +//! AM_HAL_RTC_OSC_XT +//! +//! @return None +// +//***************************************************************************** +void +am_hal_rtc_osc_select(uint32_t ui32OSC) +{ + // + // Set XT if flag is set. + // Otherwise configure for LFRC. + // + if (ui32OSC) + { + AM_REG(CLKGEN, OCTRL) |= AM_REG_CLKGEN_OCTRL_OSEL_M; + } + else + { + AM_REG(CLKGEN, OCTRL) &= ~AM_REG_CLKGEN_OCTRL_OSEL_M; + } +} + +//***************************************************************************** +// +//! @brief Enable/Start the RTC oscillator. +//! +//! Starts the RTC oscillator. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_rtc_osc_enable(void) +{ + // + // Start the RTC Oscillator. + // + AM_REG(RTC, RTCCTL) &= ~AM_REG_RTC_RTCCTL_RSTOP(1); +} + +//***************************************************************************** +// +//! @brief Disable/Stop the RTC oscillator. +//! +//! Stops the RTC oscillator. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_rtc_osc_disable(void) +{ + // + // Stop the RTC Oscillator. + // + AM_REG(RTC, RTCCTL) |= AM_REG_RTC_RTCCTL_RSTOP(1); +} + +//***************************************************************************** +// +//! @brief Configures the RTC for 12 or 24 hour time keeping. +//! +//! @param b12Hour - A 'true' configures the RTC for 12 hour time keeping. +//! +//! Configures the RTC for 12 (true) or 24 (false) hour time keeping. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_rtc_time_12hour(bool b12Hour) +{ + // + // Set the 12/24 hour bit. + // + AM_REG(RTC, RTCCTL) |= AM_REG_RTC_RTCCTL_HR1224(b12Hour); +} + +//***************************************************************************** +// +//! @brief Enable selected RTC interrupts. +//! +//! @param ui32Interrupt - desired interrupts +//! +//! Enables the RTC interrupts. +//! +//! ui32Interrupt should be an OR of the following: +//! +//! AM_HAL_RTC_INT_ALM +//! AM_HAL_RTC_INT_OF +//! AM_HAL_RTC_INT_ACC +//! AM_HAL_RTC_INT_ACF +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_rtc_int_enable(uint32_t ui32Interrupt) +{ + // + // Enable the interrupts. + // + AM_REG(RTC, INTEN) |= ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Return the enabled RTC interrupts. +//! +//! Returns the enabled RTC interrupts. +//! +//! @return enabled RTC interrupts. Return is a logical or of: +//! +//! AM_HAL_RTC_INT_ALM +//! AM_HAL_RTC_INT_OF +//! AM_HAL_RTC_INT_ACC +//! AM_HAL_RTC_INT_ACF +// +//***************************************************************************** +uint32_t +am_hal_rtc_int_enable_get(void) +{ + // + // Read the RTC interrupt enable register, and return its contents. + // + return AM_REG(RTC, INTEN); +} + +//***************************************************************************** +// +//! @brief Disable selected RTC interrupts. +//! +//! @param ui32Interrupt - desired interrupts +//! +//! Disables the RTC interrupts. +//! +//! ui32Interrupt should be an OR of the following: +//! +//! AM_HAL_RTC_INT_ALM +//! AM_HAL_RTC_INT_OF +//! AM_HAL_RTC_INT_ACC +//! AM_HAL_RTC_INT_ACF +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_rtc_int_disable(uint32_t ui32Interrupt) +{ + // + // Disable the interrupts. + // + AM_REG(RTC, INTEN) &= ~ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Sets the selected RTC interrupts. +//! +//! @param ui32Interrupt - desired interrupts +//! +//! Sets the RTC interrupts causing them to immediately trigger. +//! +//! ui32Interrupt should be an OR of the following: +//! +//! AM_HAL_RTC_INT_ALM +//! AM_HAL_RTC_INT_OF +//! AM_HAL_RTC_INT_ACC +//! AM_HAL_RTC_INT_ACF +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_rtc_int_set(uint32_t ui32Interrupt) +{ + // + // Set the interrupts. + // + AM_REG(RTC, INTSET) = ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Clear selected RTC interrupts. +//! +//! @param ui32Interrupt - desired interrupts +//! +//! Clears the RTC interrupts. +//! +//! ui32Interrupt should be an OR of the following: +//! +//! AM_HAL_RTC_INT_ALM +//! AM_HAL_RTC_INT_OF +//! AM_HAL_RTC_INT_ACC +//! AM_HAL_RTC_INT_ACF +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_rtc_int_clear(uint32_t ui32Interrupt) +{ + // + // Clear the interrupts. + // + AM_REG(RTC, INTCLR) = ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Returns the RTC interrupt status. +//! +//! @param bEnabledOnly - return the status of only the enabled interrupts. +//! +//! Returns the RTC interrupt status. +//! +//! @return Bitwise representation of the current interrupt status. +//! +//! The return value will be the logical OR of one or more of the following +//! values: +//! +//! AM_HAL_RTC_INT_ALM +//! AM_HAL_RTC_INT_OF +//! AM_HAL_RTC_INT_ACC +//! AM_HAL_RTC_INT_ACF +// +//***************************************************************************** +uint32_t +am_hal_rtc_int_status_get(bool bEnabledOnly) +{ + // + // Get the interrupt status. + // + if (bEnabledOnly) + { + uint32_t u32RetVal; + u32RetVal = AM_REG(RTC, INTSTAT); + u32RetVal &= AM_REG(RTC, INTEN); + return u32RetVal & + (AM_HAL_RTC_INT_ALM | AM_HAL_RTC_INT_OF | + AM_HAL_RTC_INT_ACC | AM_HAL_RTC_INT_ACF); + } + else + { + return (AM_REG(RTC, INTSTAT) & (AM_HAL_RTC_INT_ALM | + AM_HAL_RTC_INT_OF | + AM_HAL_RTC_INT_ACC | + AM_HAL_RTC_INT_ACF)); + } +} + +//***************************************************************************** +// +//! @brief Set the Real Time Clock counter registers. +//! +//! @param *pTime - A pointer to the time structure. +//! +//! Sets the RTC counter registers to the supplied values. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_rtc_time_set(am_hal_rtc_time_t *pTime) +{ + // + // Enable writing to the counters. + // + AM_REG(RTC, RTCCTL) |= AM_REG_RTC_RTCCTL_WRTC(1); + + // + // Write the RTCLOW register. + // + AM_REG(RTC, CTRLOW) = + AM_REG_RTC_CTRLOW_CTRHR(dec_to_bcd(pTime->ui32Hour)) | + AM_REG_RTC_CTRLOW_CTRMIN(dec_to_bcd(pTime->ui32Minute)) | + AM_REG_RTC_CTRLOW_CTRSEC(dec_to_bcd(pTime->ui32Second)) | + AM_REG_RTC_CTRLOW_CTR100(dec_to_bcd(pTime->ui32Hundredths)); + + // + // Write the RTCUP register. + // + AM_REG(RTC, CTRUP) = + AM_REG_RTC_CTRUP_CEB((pTime->ui32CenturyEnable)) | + AM_REG_RTC_CTRUP_CB((pTime->ui32Century)) | + AM_REG_RTC_CTRUP_CTRWKDY((pTime->ui32Weekday)) | + AM_REG_RTC_CTRUP_CTRYR(dec_to_bcd((pTime->ui32Year))) | + AM_REG_RTC_CTRUP_CTRMO(dec_to_bcd((pTime->ui32Month))) | + AM_REG_RTC_CTRUP_CTRDATE(dec_to_bcd((pTime->ui32DayOfMonth))); + + // + // Disable writing to the counters. + // + AM_REG(RTC, RTCCTL) |= AM_REG_RTC_RTCCTL_WRTC(0); +} + +//***************************************************************************** +// +//! @brief Get the Real Time Clock current time. +//! +//! @param *pTime - A pointer to the time structure to store the current time. +//! +//! Gets the RTC's current time +//! +//! @return 0 for success and 1 for error. +// +//***************************************************************************** +uint32_t +am_hal_rtc_time_get(am_hal_rtc_time_t *pTime) +{ + uint32_t ui32RTCLow, ui32RTCUp, ui32Value; + + // + // Read the upper and lower RTC registers. + // + ui32RTCLow = AM_REG(RTC, CTRLOW); + ui32RTCUp = AM_REG(RTC, CTRUP); + + // + // Break out the lower word. + // + ui32Value = + ((ui32RTCLow & AM_REG_RTC_CTRLOW_CTRHR_M) >> AM_REG_RTC_CTRLOW_CTRHR_S); + pTime->ui32Hour = bcd_to_dec(ui32Value); + + ui32Value = + ((ui32RTCLow & AM_REG_RTC_CTRLOW_CTRMIN_M) >> AM_REG_RTC_CTRLOW_CTRMIN_S); + pTime->ui32Minute = bcd_to_dec(ui32Value); + + ui32Value = + ((ui32RTCLow & AM_REG_RTC_CTRLOW_CTRSEC_M) >> AM_REG_RTC_CTRLOW_CTRSEC_S); + pTime->ui32Second = bcd_to_dec(ui32Value); + + ui32Value = + ((ui32RTCLow & AM_REG_RTC_CTRLOW_CTR100_M) >> AM_REG_RTC_CTRLOW_CTR100_S); + pTime->ui32Hundredths = bcd_to_dec(ui32Value); + + // + // Break out the upper word. + // + pTime->ui32ReadError = + ((ui32RTCUp & AM_REG_RTC_CTRUP_CTERR_M) >> AM_REG_RTC_CTRUP_CTERR_S); + + pTime->ui32CenturyEnable = + ((ui32RTCUp & AM_REG_RTC_CTRUP_CEB_M) >> AM_REG_RTC_CTRUP_CEB_S); + + pTime->ui32Century = + ((ui32RTCUp & AM_REG_RTC_CTRUP_CB_M) >> AM_REG_RTC_CTRUP_CB_S); + + ui32Value = + ((ui32RTCUp & AM_REG_RTC_CTRUP_CTRWKDY_M) >> AM_REG_RTC_CTRUP_CTRWKDY_S); + pTime->ui32Weekday = bcd_to_dec(ui32Value); + + ui32Value = + ((ui32RTCUp & AM_REG_RTC_CTRUP_CTRYR_M) >> AM_REG_RTC_CTRUP_CTRYR_S); + pTime->ui32Year = bcd_to_dec(ui32Value); + + ui32Value = + ((ui32RTCUp & AM_REG_RTC_CTRUP_CTRMO_M) >> AM_REG_RTC_CTRUP_CTRMO_S); + pTime->ui32Month = bcd_to_dec(ui32Value); + + ui32Value = + ((ui32RTCUp & AM_REG_RTC_CTRUP_CTRDATE_M) >> AM_REG_RTC_CTRUP_CTRDATE_S); + pTime->ui32DayOfMonth = bcd_to_dec(ui32Value); + + // + // Was there a read error? + // + if (pTime->ui32ReadError) + { + return 1; + } + else + { + return 0; + } +} + +//***************************************************************************** +// +//! @brief Sets the alarm repeat interval. +//! +//! @param ui32RepeatInterval the desired repeat interval. +//! +//! Sets the alarm repeat interval. +//! +//! Valid values for ui32RepeatInterval: +//! +//! AM_HAL_RTC_ALM_RPT_DIS +//! AM_HAL_RTC_ALM_RPT_YR +//! AM_HAL_RTC_ALM_RPT_MTH +//! AM_HAL_RTC_ALM_RPT_WK +//! AM_HAL_RTC_ALM_RPT_DAY +//! AM_HAL_RTC_ALM_RPT_HR +//! AM_HAL_RTC_ALM_RPT_MIN +//! AM_HAL_RTC_ALM_RPT_SEC +//! AM_HAL_RTC_ALM_RPT_10TH +//! AM_HAL_RTC_ALM_RPT_100TH +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_rtc_alarm_interval_set(uint32_t ui32RepeatInterval) +{ + uint32_t ui32RptInt, ui32Alm100, ui32Value; + + switch(ui32RepeatInterval) + { + // + // If repeat every 10th set RPT and ALM100 field accordinly + // + case AM_HAL_RTC_ALM_RPT_10TH: + ui32RptInt = AM_HAL_RTC_ALM_RPT_SEC; + ui32Alm100 = AM_HAL_RTC_ALM100_10TH; + break; + // + // If repeat every 100th set RPT and ALM100 field accordinly + // + case AM_HAL_RTC_ALM_RPT_100TH: + ui32RptInt = AM_HAL_RTC_ALM_RPT_SEC; + ui32Alm100 = AM_HAL_RTC_ALM100_100TH; + break; + // + // Otherwise set RPT as value passed. ALM100 values need to be 0xnn + // in this setting where n = 0-9. + // + default: + // + // Get the current value of the ALM100 field. + // + ui32Value = AM_BFR(RTC, ALMLOW, ALM100); + + // + // If ALM100 was previous EVERY_10TH or EVERY_100TH reset to zero + // otherwise keep previous setting. + // + ui32Alm100 = ui32Value >= 0xF0 ? 0 : ui32Value; + + // + // Set RPT value to value passed. + // + ui32RptInt = ui32RepeatInterval; + break; + } + + // + // Write the interval to the register. + // + AM_BFW(RTC, RTCCTL, RPT, ui32RptInt); + + // + // Write the Alarm 100 bits in the ALM100 register. + // + AM_BFW(RTC, ALMLOW, ALM100, ui32Alm100); +} + +//***************************************************************************** +// +//! @brief Sets the RTC's Alarm. +//! +//! @param *pTime - A pointer to the time structure. +//! @param ui32RepeatInterval - the desired alarm repeat interval. +//! +//! Set the Real Time Clock Alarm Parameters. +//! +//! Valid values for ui32RepeatInterval: +//! +//! AM_HAL_RTC_ALM_RPT_DIS +//! AM_HAL_RTC_ALM_RPT_YR +//! AM_HAL_RTC_ALM_RPT_MTH +//! AM_HAL_RTC_ALM_RPT_WK +//! AM_HAL_RTC_ALM_RPT_DAY +//! AM_HAL_RTC_ALM_RPT_HR +//! AM_HAL_RTC_ALM_RPT_MIN +//! AM_HAL_RTC_ALM_RPT_SEC +//! AM_HAL_RTC_ALM_RPT_10TH +//! AM_HAL_RTC_ALM_RPT_EVERY_100TH +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_rtc_alarm_set(am_hal_rtc_time_t *pTime, uint32_t ui32RepeatInterval) +{ + uint8_t ui8Value = 0; + + // + // Write the interval to the register. + // + AM_REG(RTC, RTCCTL) |= + AM_REG_RTC_RTCCTL_RPT(ui32RepeatInterval > 0x7 ? 0x7 : ui32RepeatInterval); + + // + // Check if the interval is 10th or every 100th and track it in ui8Value. + // + if (ui32RepeatInterval == AM_HAL_RTC_ALM_RPT_10TH) + { + ui8Value = 0xF0; + } + else if (ui32RepeatInterval == AM_HAL_RTC_ALM_RPT_100TH) + { + ui8Value = 0xFF; + } + + // + // Write the ALMUP register. + // + AM_REG(RTC, ALMUP) = + AM_REG_RTC_ALMUP_ALMWKDY((pTime->ui32Weekday)) | + AM_REG_RTC_ALMUP_ALMMO(dec_to_bcd((pTime->ui32Month))) | + AM_REG_RTC_ALMUP_ALMDATE(dec_to_bcd((pTime->ui32DayOfMonth))); + + // + // Write the ALMLOW register. + // + AM_REG(RTC, ALMLOW) = + AM_REG_RTC_ALMLOW_ALMHR(dec_to_bcd(pTime->ui32Hour)) | + AM_REG_RTC_ALMLOW_ALMMIN(dec_to_bcd(pTime->ui32Minute)) | + AM_REG_RTC_ALMLOW_ALMSEC(dec_to_bcd(pTime->ui32Second)) | + AM_REG_RTC_ALMLOW_ALM100(dec_to_bcd(pTime->ui32Hundredths) | ui8Value); +} + +//***************************************************************************** +// +//! @brief Get the Real Time Clock Alarm Parameters +//! +//! @param *pTime - A pointer to the time structure to store the current alarm. +//! +//! Gets the RTC's Alarm time +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_rtc_alarm_get(am_hal_rtc_time_t *pTime) +{ + uint32_t ui32ALMLow, ui32ALMUp, ui32Value; + + // + // Read the upper and lower RTC registers. + // + ui32ALMLow = AM_REG(RTC, ALMLOW); + ui32ALMUp = AM_REG(RTC, ALMUP); + + // + // Break out the lower word. + // + ui32Value = + ((ui32ALMLow & AM_REG_RTC_ALMLOW_ALMHR_M) >> AM_REG_RTC_ALMLOW_ALMHR_S); + pTime->ui32Hour = bcd_to_dec(ui32Value); + + ui32Value = + ((ui32ALMLow & AM_REG_RTC_ALMLOW_ALMMIN_M) >> AM_REG_RTC_ALMLOW_ALMMIN_S); + pTime->ui32Minute = bcd_to_dec(ui32Value); + + ui32Value = + ((ui32ALMLow & AM_REG_RTC_ALMLOW_ALMSEC_M) >> AM_REG_RTC_ALMLOW_ALMSEC_S); + pTime->ui32Second = bcd_to_dec(ui32Value); + + ui32Value = + ((ui32ALMLow & AM_REG_RTC_ALMLOW_ALM100_M) >> AM_REG_RTC_ALMLOW_ALM100_S); + pTime->ui32Hundredths = bcd_to_dec(ui32Value); + + // + // Break out the upper word. + // + pTime->ui32ReadError = 0; + pTime->ui32CenturyEnable = 0; + pTime->ui32Century = 0; + + ui32Value = + ((ui32ALMUp & AM_REG_RTC_ALMUP_ALMWKDY_M) >> AM_REG_RTC_ALMUP_ALMWKDY_S); + pTime->ui32Weekday = bcd_to_dec(ui32Value); + + pTime->ui32Year = 0; + + ui32Value = + ((ui32ALMUp & AM_REG_RTC_ALMUP_ALMMO_M) >> AM_REG_RTC_ALMUP_ALMMO_S); + pTime->ui32Month = bcd_to_dec(ui32Value); + + ui32Value = + ((ui32ALMUp & AM_REG_RTC_ALMUP_ALMDATE_M) >> AM_REG_RTC_ALMUP_ALMDATE_S); + pTime->ui32DayOfMonth = bcd_to_dec(ui32Value); +} + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_rtc.h b/bsp/apollo2/libraries/drivers/hal/am_hal_rtc.h new file mode 100644 index 0000000000..9304a6c67f --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_rtc.h @@ -0,0 +1,185 @@ +//***************************************************************************** +// +// am_hal_rtc.h +//! @file +//! +//! @brief Functions for interfacing and accessing the Real-Time Clock (RTC). +//! +//! @addtogroup rtc2 Real-Time Clock (RTC) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_RTC_H +#define AM_HAL_RTC_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +//! @name OSC Start and Stop +//! @brief OSC Start and Stop defines. +//! +//! OSC Start and Stop defines to be used with \e am_hal_clkgen_osc_x(). +//! @{ +// +//***************************************************************************** +#define AM_HAL_RTC_OSC_LFRC 0x1 +#define AM_HAL_RTC_OSC_XT 0x0 +//! @} + +//***************************************************************************** +// +//! @name RTC Interrupts +//! @brief Macro definitions for RTC interrupt status bits. +//! +//! These macros correspond to the bits in the RTC interrupt status register. +//! They may be used with any of the \e am_hal_rtc_int_x() functions. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_RTC_INT_ALM AM_REG_RTC_INTEN_ALM_M +#define AM_HAL_RTC_INT_OF AM_REG_RTC_INTEN_OF_M +#define AM_HAL_RTC_INT_ACC AM_REG_RTC_INTEN_ACC_M +#define AM_HAL_RTC_INT_ACF AM_REG_RTC_INTEN_ACF_M +//! @} + +//***************************************************************************** +// +//! @name RTC Alarm Repeat Interval. +//! @brief Macro definitions for the RTC alarm repeat interval. +//! +//! These macros correspond to the RPT bits in the RTCCTL register. +//! They may be used with the \e am_hal_rtc_alarm_interval_set() function. +//! +//! Note: AM_HAL_RTC_ALM_RPT_10TH and AM_HAL_RTC_ALM_RPT_100TH do not +//! correspond to the RPT bits but are used in conjunction with setting the +//! ALM100 bits in the ALMLOW register. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_RTC_ALM_RPT_DIS 0x0 +#define AM_HAL_RTC_ALM_RPT_YR 0x1 +#define AM_HAL_RTC_ALM_RPT_MTH 0x2 +#define AM_HAL_RTC_ALM_RPT_WK 0x3 +#define AM_HAL_RTC_ALM_RPT_DAY 0x4 +#define AM_HAL_RTC_ALM_RPT_HR 0x5 +#define AM_HAL_RTC_ALM_RPT_MIN 0x6 +#define AM_HAL_RTC_ALM_RPT_SEC 0x7 +#define AM_HAL_RTC_ALM_RPT_10TH 0x8 +#define AM_HAL_RTC_ALM_RPT_100TH 0x9 +//! @} + +//***************************************************************************** +// +//! @name RTC Alarm 100 Interval. +//! @brief Macro definitions for the RTC alarm ms intervals. +//! +//! These macros are used inside the #am_hal_rtc_alarm_interval_set function +//! when 10ms and 100ms repeated alarm intervals are desired. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_RTC_ALM100_DEFAULT 0x00 +#define AM_HAL_RTC_ALM100_10TH 0xF0 +#define AM_HAL_RTC_ALM100_100TH 0xFF +//! @} + +//***************************************************************************** +// +//! @brief The basic time structure used by the HAL for RTC interaction. +//! +//! All values are positive whole numbers. The HAL routines convert back and +//! forth to BCD. +// +//***************************************************************************** +typedef struct am_hal_rtc_time_struct +{ + uint32_t ui32ReadError; + uint32_t ui32CenturyEnable; + uint32_t ui32Weekday; + uint32_t ui32Century; + uint32_t ui32Year; + uint32_t ui32Month; + uint32_t ui32DayOfMonth; + uint32_t ui32Hour; + uint32_t ui32Minute; + uint32_t ui32Second; + uint32_t ui32Hundredths; +}am_hal_rtc_time_t; + +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern void am_hal_rtc_osc_select(uint32_t ui32OSC); +extern void am_hal_rtc_osc_enable(void); +extern void am_hal_rtc_osc_disable(void); +extern void am_hal_rtc_time_12hour(bool b12Hour); +extern void am_hal_rtc_time_set(am_hal_rtc_time_t *pTime); +extern uint32_t am_hal_rtc_time_get(am_hal_rtc_time_t *pTime); +extern void am_hal_rtc_alarm_interval_set(uint32_t ui32RepeatInterval); +extern void am_hal_rtc_alarm_set(am_hal_rtc_time_t *pTime, + uint32_t ui32RepeatInterval); +extern void am_hal_rtc_alarm_get(am_hal_rtc_time_t *pTime); +extern void am_hal_rtc_int_enable(uint32_t ui32Interrupt); +extern uint32_t am_hal_rtc_int_enable_get(void); +extern void am_hal_rtc_int_disable(uint32_t ui32Interrupt); +extern void am_hal_rtc_int_clear(uint32_t ui32Interrupt); +extern void am_hal_rtc_int_set(uint32_t ui32Interrupt); +extern uint32_t am_hal_rtc_int_status_get(bool bEnabledOnly); + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_RTC_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_stimer.c b/bsp/apollo2/libraries/drivers/hal/am_hal_stimer.c new file mode 100644 index 0000000000..0cdd706c9e --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_stimer.c @@ -0,0 +1,525 @@ +//***************************************************************************** +// +// am_hal_stimer.c +//! @file +//! +//! @brief Functions for interfacing with the system timer (STIMER). +//! +//! @addtogroup stimer2 System Timer (STIMER) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +//! @brief Set up the stimer. +//! +//! @param ui32STimerConfig is the value to load into the configuration reg. +//! +//! This function should be used to perform the initial set-up of the +//! stimer. +//! +//! @return The 32-bit current config of the STimer Config register +// +//***************************************************************************** +uint32_t +am_hal_stimer_config(uint32_t ui32STimerConfig) +{ + uint32_t ui32CurrVal; + + // + // Read the current config + // + ui32CurrVal = AM_REG(CTIMER, STCFG); + + // + // Write our configuration value. + // + AM_REG(CTIMER, STCFG) = ui32STimerConfig; + + // + // If all of the clock sources are not HFRC, disable LDO when sleeping if timers are enabled. + // + if ( (AM_BFR(CTIMER, STCFG, CLKSEL) == AM_REG_CTIMER_STCFG_CLKSEL_HFRC_DIV16) || + (AM_BFR(CTIMER, STCFG, CLKSEL) == AM_REG_CTIMER_STCFG_CLKSEL_HFRC_DIV256) ) + { + AM_BFW(PWRCTRL, MISCOPT, DIS_LDOLPMODE_TIMERS, 0); + } + else + { + AM_BFW(PWRCTRL, MISCOPT, DIS_LDOLPMODE_TIMERS, 1); + } + return ui32CurrVal; +} + +//***************************************************************************** +// +//! @brief Get the current stimer value. +//! +//! This function can be used to read, uninvasively, the value in the stimer. +//! +//! @return The 32-bit value from the STimer counter register. +// +//***************************************************************************** +uint32_t +am_hal_stimer_counter_get(void) +{ + return AM_REG(CTIMER, STTMR); +} + +//***************************************************************************** +// +//! @brief Clear the stimer counter. +//! +//! This function clears the STimer Counter and leaves the stimer running. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_stimer_counter_clear(void) +{ + // + // Set the clear bit + // + AM_REG(CTIMER, STCFG) |= AM_REG_CTIMER_STCFG_CLEAR_M; + + // + // Reset the clear bit + // + AM_REG(CTIMER, STCFG) &= ~AM_REG_CTIMER_STCFG_CLEAR_M; +} + +//***************************************************************************** +// +//! @brief Set the compare value. +//! +//! @param ui32CmprInstance is the compare register instance number (0-7). +//! @param ui32Delta is the value to add to the STimer counter and load into +//! the comparator register. +//! +//! NOTE: There is no way to set an absolute value into a comparator register. +//! Only deltas added to the STimer counter can be written to the compare +//! registers. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_stimer_compare_delta_set(uint32_t ui32CmprInstance, uint32_t ui32Delta) +{ + if ( ui32CmprInstance > 7 ) + { + return; + } + + AM_REGVAL(AM_REG_STIMER_COMPARE(0, ui32CmprInstance)) = ui32Delta; +} + +//***************************************************************************** +// +//! @brief Get the current stimer compare register value. +//! +//! @param ui32CmprInstance is the compare register instance number (0-7). +//! +//! This function can be used to read the value in an stimer compare register. +//! +//! +//! @return None. +// +//***************************************************************************** +uint32_t +am_hal_stimer_compare_get(uint32_t ui32CmprInstance) +{ + if ( ui32CmprInstance > 7 ) + { + return 0; + } + + return AM_REGVAL(AM_REG_STIMER_COMPARE(0, ui32CmprInstance)); +} + +//***************************************************************************** +// +//! @brief Start capturing data with the specified capture register. +//! +//! @param ui32CaptureNum is the Capture Register Number to read (0-3). +//! ui32GPIONumber is the pin number. +//! bPolarity: false (0) = Capture on low to high transition. +//! true (1) = Capture on high to low transition. +//! +//! Use this function to start capturing. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_stimer_capture_start(uint32_t ui32CaptureNum, + uint32_t ui32GPIONumber, + bool bPolarity) +{ + uint32_t ui32CapCtrl; + + if ( ui32GPIONumber > (AM_HAL_GPIO_MAX_PADS-1) ) + { + return; + } + + // + // Set the polarity and pin selection in the GPIO block. + // + switch (ui32CaptureNum) + { + case 0: + AM_BFW(GPIO, STMRCAP, STPOL0, bPolarity); + AM_BFW(GPIO, STMRCAP, STSEL0, ui32GPIONumber); + ui32CapCtrl = AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_A_M; + break; + case 1: + AM_BFW(GPIO, STMRCAP, STPOL1, bPolarity); + AM_BFW(GPIO, STMRCAP, STSEL1, ui32GPIONumber); + ui32CapCtrl = AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_B_M; + break; + case 2: + AM_BFW(GPIO, STMRCAP, STPOL2, bPolarity); + AM_BFW(GPIO, STMRCAP, STSEL2, ui32GPIONumber); + ui32CapCtrl = AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_C_M; + break; + case 3: + AM_BFW(GPIO, STMRCAP, STPOL3, bPolarity); + AM_BFW(GPIO, STMRCAP, STSEL3, ui32GPIONumber); + ui32CapCtrl = AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_D_M; + break; + default: + return; // error concealment. + } + + // + // Enable it in the CTIMER Block + // + AM_REG(CTIMER, CAPTURE_CONTROL) |= ui32CapCtrl; +} + +//***************************************************************************** +// +//! @brief Start capturing data with the specified capture register. +//! +//! @param ui32CaptureNum is the Capture Register Number to read. +//! +//! Use this function to start capturing. +//! +//! @return None. +// +//***************************************************************************** +void am_hal_stimer_capture_stop(uint32_t ui32CaptureNum) +{ + // + // Disable it in the CTIMER block. + // + AM_REG(CTIMER, CAPTURE_CONTROL) &= + ~(AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_A_M << + ((AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_B_S - + AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_A_S) * ui32CaptureNum)); +} + +//***************************************************************************** +// +//! @brief Get the current stimer capture register value. +//! +//! @param ui32CaptureNum is the Capture Register Number to read. +//! +//! This function can be used to read the value in an stimer capture register. +//! +//! +//! @return None. +// +//***************************************************************************** +uint32_t am_hal_stimer_capture_get(uint32_t ui32CaptureNum) +{ + if ( ui32CaptureNum > 7 ) + { + return 0; + } + + return AM_REGVAL(AM_REG_STIMER_CAPTURE(0, ui32CaptureNum)); +} + +//***************************************************************************** +// +//! @brief Enables the selected system timer interrupt. +//! +//! @param ui32Interrupt is the interrupt to be used. +//! +//! This function will enable the selected interrupts in the STIMER interrupt +//! enable register. In order to receive an interrupt from an stimer component, +//! you will need to enable the interrupt for that component in this main +//! register, as well as in the stimer configuration register (accessible though +//! am_hal_stimer_config()), and in the NVIC. +//! +//! ui32Interrupt should be the logical OR of one or more of the following +//! values: +//! +//! AM_HAL_STIMER_INT_COMPAREA +//! AM_HAL_STIMER_INT_COMPAREB +//! AM_HAL_STIMER_INT_COMPAREC +//! AM_HAL_STIMER_INT_COMPARED +//! AM_HAL_STIMER_INT_COMPAREE +//! AM_HAL_STIMER_INT_COMPAREF +//! AM_HAL_STIMER_INT_COMPAREG +//! AM_HAL_STIMER_INT_COMPAREH +//! +//! AM_HAL_STIMER_INT_OVERFLOW +//! +//! AM_HAL_STIMER_INT_CAPTUREA +//! AM_HAL_STIMER_INT_CAPTUREB +//! AM_HAL_STIMER_INT_CAPTUREC +//! AM_HAL_STIMER_INT_CAPTURED +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_stimer_int_enable(uint32_t ui32Interrupt) +{ + // + // Enable the interrupt at the module level. + // + AM_REGn(CTIMER, 0, STMINTEN) |= ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Return the enabled stimer interrupts. +//! +//! This function will return all enabled interrupts in the STIMER +//! interrupt enable register. +//! +//! @return return enabled interrupts. This will be a logical or of: +//! +//! AM_HAL_STIMER_INT_COMPAREA +//! AM_HAL_STIMER_INT_COMPAREB +//! AM_HAL_STIMER_INT_COMPAREC +//! AM_HAL_STIMER_INT_COMPARED +//! AM_HAL_STIMER_INT_COMPAREE +//! AM_HAL_STIMER_INT_COMPAREF +//! AM_HAL_STIMER_INT_COMPAREG +//! AM_HAL_STIMER_INT_COMPAREH +//! +//! AM_HAL_STIMER_INT_OVERFLOW +//! +//! AM_HAL_STIMER_INT_CAPTUREA +//! AM_HAL_STIMER_INT_CAPTUREB +//! AM_HAL_STIMER_INT_CAPTUREC +//! AM_HAL_STIMER_INT_CAPTURED +//! +//! @return Return the enabled timer interrupts. +// +//***************************************************************************** +uint32_t +am_hal_stimer_int_enable_get(void) +{ + // + // Return enabled interrupts. + // + return AM_REGn(CTIMER, 0, STMINTEN); +} + +//***************************************************************************** +// +//! @brief Disables the selected stimer interrupt. +//! +//! @param ui32Interrupt is the interrupt to be used. +//! +//! This function will disable the selected interrupts in the STIMER +//! interrupt register. +//! +//! ui32Interrupt should be the logical OR of one or more of the following +//! values: +//! +//! AM_HAL_STIMER_INT_COMPAREA +//! AM_HAL_STIMER_INT_COMPAREB +//! AM_HAL_STIMER_INT_COMPAREC +//! AM_HAL_STIMER_INT_COMPARED +//! AM_HAL_STIMER_INT_COMPAREE +//! AM_HAL_STIMER_INT_COMPAREF +//! AM_HAL_STIMER_INT_COMPAREG +//! AM_HAL_STIMER_INT_COMPAREH +//! +//! AM_HAL_STIMER_INT_OVERFLOW +//! +//! AM_HAL_STIMER_INT_CAPTUREA +//! AM_HAL_STIMER_INT_CAPTUREB +//! AM_HAL_STIMER_INT_CAPTUREC +//! AM_HAL_STIMER_INT_CAPTURED +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_stimer_int_disable(uint32_t ui32Interrupt) +{ + // + // Disable the interrupt at the module level. + // + AM_REGn(CTIMER, 0, STMINTEN) &= ~ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Sets the selected stimer interrupt. +//! +//! @param ui32Interrupt is the interrupt to be used. +//! +//! This function will set the selected interrupts in the STIMER +//! interrupt register. +//! +//! ui32Interrupt should be the logical OR of one or more of the following +//! values: +//! +//! AM_HAL_STIMER_INT_COMPAREA +//! AM_HAL_STIMER_INT_COMPAREB +//! AM_HAL_STIMER_INT_COMPAREC +//! AM_HAL_STIMER_INT_COMPARED +//! AM_HAL_STIMER_INT_COMPAREE +//! AM_HAL_STIMER_INT_COMPAREF +//! AM_HAL_STIMER_INT_COMPAREG +//! AM_HAL_STIMER_INT_COMPAREH +//! +//! AM_HAL_STIMER_INT_OVERFLOW +//! +//! AM_HAL_STIMER_INT_CAPTUREA +//! AM_HAL_STIMER_INT_CAPTUREB +//! AM_HAL_STIMER_INT_CAPTUREC +//! AM_HAL_STIMER_INT_CAPTURED +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_stimer_int_set(uint32_t ui32Interrupt) +{ + // + // Set the interrupts. + // + AM_REGn(CTIMER, 0, STMINTSET) = ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Clears the selected stimer interrupt. +//! +//! @param ui32Interrupt is the interrupt to be used. +//! +//! This function will clear the selected interrupts in the STIMER +//! interrupt register. +//! +//! ui32Interrupt should be the logical OR of one or more of the following +//! values: +//! +//! AM_HAL_STIMER_INT_COMPAREA +//! AM_HAL_STIMER_INT_COMPAREB +//! AM_HAL_STIMER_INT_COMPAREC +//! AM_HAL_STIMER_INT_COMPARED +//! AM_HAL_STIMER_INT_COMPAREE +//! AM_HAL_STIMER_INT_COMPAREF +//! AM_HAL_STIMER_INT_COMPAREG +//! AM_HAL_STIMER_INT_COMPAREH +//! +//! AM_HAL_STIMER_INT_OVERFLOW +//! +//! AM_HAL_STIMER_INT_CAPTUREA +//! AM_HAL_STIMER_INT_CAPTUREB +//! AM_HAL_STIMER_INT_CAPTUREC +//! AM_HAL_STIMER_INT_CAPTURED +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_stimer_int_clear(uint32_t ui32Interrupt) +{ + // + // Disable the interrupt at the module level. + // + AM_REGn(CTIMER, 0, STMINTCLR) = ui32Interrupt; +} + + +//***************************************************************************** +// +//! @brief Returns either the enabled or raw stimer interrupt status. +//! +//! This function will return the stimer interrupt status. +//! +//! @bEnabledOnly if true returns the status of the enabled interrupts +//! only. +//! +//! The return value will be the logical OR of one or more of the following +//! values: +//! +//! +//! @return Returns the stimer interrupt status. +// +//***************************************************************************** +uint32_t +am_hal_stimer_int_status_get(bool bEnabledOnly) +{ + // + // Return the desired status. + // + uint32_t ui32RetVal = AM_REGn(CTIMER, 0, STMINTSTAT); + + if ( bEnabledOnly ) + { + ui32RetVal &= AM_REGn(CTIMER, 0, STMINTEN); + } + + return ui32RetVal; +} + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_stimer.h b/bsp/apollo2/libraries/drivers/hal/am_hal_stimer.h new file mode 100644 index 0000000000..bd4b09feae --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_stimer.h @@ -0,0 +1,242 @@ +//***************************************************************************** +// +// am_hal_stimer.h +//! @file +//! +//! @brief Functions for accessing and configuring the STIMER. +//! +//! @addtogroup stimer2 Counter/Timer (STIMER) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_STIMER_H +#define AM_HAL_STIMER_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +// +// Compute address of a given COMPARE or CAPTURE register. +// Note - For Apollo2, the parameter n should be 0 (as only 1 stimer module +// exists) and the parameter r should be 0-7 (compare) or 0-3 (capture). +// +#define AM_REG_STIMER_COMPARE(n, r) (AM_REG_CTIMERn(n) + \ + AM_REG_CTIMER_SCMPR0_O + (r * 4)) + +#define AM_REG_STIMER_CAPTURE(n, r) (AM_REG_CTIMERn(n) + \ + AM_REG_CTIMER_SCAPT0_O + (r * 4)) + +//***************************************************************************** +// +//! @name Interrupt Status Bits +//! @brief Interrupt Status Bits for enable/disble use +//! +//! These macros may be used to set and clear interrupt bits +//! @{ +// +//***************************************************************************** +#define AM_HAL_STIMER_INT_COMPAREA AM_REG_CTIMER_STMINTSTAT_COMPAREA_M +#define AM_HAL_STIMER_INT_COMPAREB AM_REG_CTIMER_STMINTSTAT_COMPAREB_M +#define AM_HAL_STIMER_INT_COMPAREC AM_REG_CTIMER_STMINTSTAT_COMPAREC_M +#define AM_HAL_STIMER_INT_COMPARED AM_REG_CTIMER_STMINTSTAT_COMPARED_M +#define AM_HAL_STIMER_INT_COMPAREE AM_REG_CTIMER_STMINTSTAT_COMPAREE_M +#define AM_HAL_STIMER_INT_COMPAREF AM_REG_CTIMER_STMINTSTAT_COMPAREF_M +#define AM_HAL_STIMER_INT_COMPAREG AM_REG_CTIMER_STMINTSTAT_COMPAREG_M +#define AM_HAL_STIMER_INT_COMPAREH AM_REG_CTIMER_STMINTSTAT_COMPAREH_M + +#define AM_HAL_STIMER_INT_OVERFLOW AM_REG_CTIMER_STMINTSTAT_OVERFLOW_M + +#define AM_HAL_STIMER_INT_CAPTUREA AM_REG_CTIMER_STMINTSTAT_CAPTUREA_M +#define AM_HAL_STIMER_INT_CAPTUREB AM_REG_CTIMER_STMINTSTAT_CAPTUREB_M +#define AM_HAL_STIMER_INT_CAPTUREC AM_REG_CTIMER_STMINTSTAT_CAPTUREC_M +#define AM_HAL_STIMER_INT_CAPTURED AM_REG_CTIMER_STMINTSTAT_CAPTURED_M + +//! @} + + + +//***************************************************************************** +// +//! @name STimer Configuration Bits +//! @brief Interrupt Status Bits for enable/disble use +//! +//! These macros may be used to set and clear interrupt bits +//! @{ +// +//***************************************************************************** +#define AM_HAL_STIMER_CFG_THAW \ + AM_REG_CTIMER_STCFG_FREEZE_THAW +#define AM_HAL_STIMER_CFG_FREEZE \ + AM_REG_CTIMER_STCFG_FREEZE_FREEZE +#define AM_HAL_STIMER_CFG_RUN \ + AM_REG_CTIMER_STCFG_CLEAR_RUN +#define AM_HAL_STIMER_CFG_CLEAR \ + AM_REG_CTIMER_STCFG_CLEAR_CLEAR +#define AM_HAL_STIMER_CFG_COMPARE_A_ENABLE \ + AM_REG_CTIMER_STCFG_COMPARE_A_EN_ENABLE +#define AM_HAL_STIMER_CFG_COMPARE_B_ENABLE \ + AM_REG_CTIMER_STCFG_COMPARE_B_EN_ENABLE +#define AM_HAL_STIMER_CFG_COMPARE_C_ENABLE \ + AM_REG_CTIMER_STCFG_COMPARE_C_EN_ENABLE +#define AM_HAL_STIMER_CFG_COMPARE_D_ENABLE \ + AM_REG_CTIMER_STCFG_COMPARE_D_EN_ENABLE +#define AM_HAL_STIMER_CFG_COMPARE_E_ENABLE \ + AM_REG_CTIMER_STCFG_COMPARE_E_EN_ENABLE +#define AM_HAL_STIMER_CFG_COMPARE_F_ENABLE \ + AM_REG_CTIMER_STCFG_COMPARE_F_EN_ENABLE +#define AM_HAL_STIMER_CFG_COMPARE_G_ENABLE \ + AM_REG_CTIMER_STCFG_COMPARE_G_EN_ENABLE +#define AM_HAL_STIMER_CFG_COMPARE_H_ENABLE \ + AM_REG_CTIMER_STCFG_COMPARE_H_EN_ENABLE + +//! @} + +//***************************************************************************** +// +//! @name Clock Configuration options +//! @brief STimer Configuration register options. +//! +//! These options are to be used with the am_hal_stimer_config() function. +//! @{ +// +//***************************************************************************** +#define AM_HAL_STIMER_NO_CLK \ + AM_REG_CTIMER_STCFG_CLKSEL(AM_REG_CTIMER_STCFG_CLKSEL_NOCLK) +#define AM_HAL_STIMER_HFRC_3MHZ \ + AM_REG_CTIMER_STCFG_CLKSEL(AM_REG_CTIMER_STCFG_CLKSEL_HFRC_DIV16) +#define AM_HAL_STIMER_HFRC_187_5KHZ \ + AM_REG_CTIMER_STCFG_CLKSEL(AM_REG_CTIMER_STCFG_CLKSEL_HFRC_DIV256) +#define AM_HAL_STIMER_XTAL_32KHZ \ + AM_REG_CTIMER_STCFG_CLKSEL(AM_REG_CTIMER_STCFG_CLKSEL_XTAL_DIV1) +#define AM_HAL_STIMER_XTAL_16KHZ \ + AM_REG_CTIMER_STCFG_CLKSEL(AM_REG_CTIMER_STCFG_CLKSEL_XTAL_DIV2) +#define AM_HAL_STIMER_XTAL_1KHZ \ + AM_REG_CTIMER_STCFG_CLKSEL(AM_REG_CTIMER_STCFG_CLKSEL_XTAL_DIV32) +#define AM_HAL_STIMER_LFRC_1KHZ \ + AM_REG_CTIMER_STCFG_CLKSEL(AM_REG_CTIMER_STCFG_CLKSEL_LFRC_DIV1) +#define AM_HAL_STIMER_HFRC_CTIMER0A \ + AM_REG_CTIMER_STCFG_CLKSEL(AM_REG_CTIMER_STCFG_CLKSEL_CTIMER0A) +#define AM_HAL_STIMER_HFRC_CTIMER0B \ + AM_REG_CTIMER_STCFG_CLKSEL(AM_REG_CTIMER_STCFG_CLKSEL_CTIMER0B) +//! @} + + + +//***************************************************************************** +// +//! @name Capture Control Register options. +//! @brief Configuration options for capture control register. +//! +//! These options are to be used with the am_hal_stimer_capture_control_set +//! function. +//! @{ +// +//***************************************************************************** +#define AM_HAL_STIMER_CAPTURE_A_ENABLE \ + AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_A_ENABLE +#define AM_HAL_STIMER_CAPTURE_B_ENABLE \ + AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_B_ENABLE +#define AM_HAL_STIMER_CAPTURE_C_ENABLE \ + AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_C_ENABLE +#define AM_HAL_STIMER_CAPTURE_D_ENABLE \ + AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_D_ENABLE + +//! @} + + +//***************************************************************************** +// +// +// +//***************************************************************************** + +//***************************************************************************** +// +// Stimer configuration structure +// +//***************************************************************************** +typedef struct +{ + // + //! Configuration options for the STIMER + // + uint32_t ui32STimerConfig; +} +am_hal_stimer_config_t; + + + +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern uint32_t am_hal_stimer_config(uint32_t ui32STimerConfig); +extern uint32_t am_hal_stimer_counter_get(void); +extern void am_hal_stimer_counter_clear(void); +extern void am_hal_stimer_compare_delta_set(uint32_t ui32CmprInstance, + uint32_t ui32Delta); +extern uint32_t am_hal_stimer_compare_get(uint32_t ui32CmprInstance); +extern void am_hal_stimer_capture_start(uint32_t ui32CaptureNum, + uint32_t ui32GPIONumber, + bool bPolarity); +extern void am_hal_stimer_capture_stop(uint32_t ui32CaptureNum); +extern uint32_t am_hal_stimer_capture_get(uint32_t ui32CaptureNum); +extern void am_hal_stimer_int_enable(uint32_t ui32Interrupt); +extern uint32_t am_hal_stimer_int_enable_get(void); +extern void am_hal_stimer_int_disable(uint32_t ui32Interrupt); +extern void am_hal_stimer_int_set(uint32_t ui32Interrupt); +extern void am_hal_stimer_int_clear(uint32_t ui32Interrupt); +extern uint32_t am_hal_stimer_int_status_get(bool bEnabledOnly); + + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_STIMER_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_sysctrl.c b/bsp/apollo2/libraries/drivers/hal/am_hal_sysctrl.c new file mode 100644 index 0000000000..50e0b67915 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_sysctrl.c @@ -0,0 +1,851 @@ +//***************************************************************************** +// +// am_hal_sysctrl.c +//! @file +//! +//! @brief Functions for interfacing with the M4F system control registers +//! +//! @addtogroup sysctrl2 System Control (SYSCTRL) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +// Local macro constants +// +//***************************************************************************** +// +// Define ZX workaround values. +// These values are defined by the factory. +// +#define COREZXVALUE 0x07 +#define MEMZXVALUE 0x07 + +// +// Define values for g_ui32CoreBuck, which indicates which timer carries +// the signal for the CORE Buck, and which also implies that the other timer +// carries the signal for the MEM buck. +// +#define COREBUCK_TIMERA 1 // Core buck signal comes in on timer A +#define COREBUCK_TIMERB 2 // Core buck signal comes in on timer B + +// +// Define the bit values for static function g_buckZX_chk; +// +#define CHKBUCKZX_BUCKS 0x01 // The bucks are enabled +#define CHKBUCKZX_REV 0x02 // This chip rev needs the workaround +#define CHKBUCKZX_TIMER 0x04 // A valid timer has been allocated +#define CHKBUCKZX_DEVEN 0x08 // Devices are powered up and enabled + +//***************************************************************************** +// +// Prototypes +// +//***************************************************************************** +static void am_hal_sysctrl_buckA_ctimer_isr(void); +static void am_hal_sysctrl_buckB_ctimer_isr(void); + +//***************************************************************************** +// +// Globals +// +//***************************************************************************** +static volatile uint32_t g_ui32BuckTimer = 0; +static volatile uint32_t g_ui32BuckInputs = 0; +static volatile bool g_bBuckRestoreComplete = false; +static volatile bool g_bBuckTimed = false; +static uint32_t g_ui32SaveCoreBuckZX, g_ui32SaveMemBuckZX; +static uint32_t g_buckZX_chk = 0; +static volatile uint32_t g_ui32CoreBuck; + +// +// Timer configuration for BUCK inputs. +// +static const am_hal_ctimer_config_t g_sBuckTimer = +{ + // Don't link timers. + 0, + + // Set up Timer0A. + (AM_HAL_CTIMER_FN_ONCE | + AM_HAL_CTIMER_INT_ENABLE | + AM_HAL_CTIMER_BUCK), + + // Set up Timer0B. + (AM_HAL_CTIMER_FN_ONCE | + AM_HAL_CTIMER_INT_ENABLE | + AM_HAL_CTIMER_BUCK), +}; + +//***************************************************************************** +// +// Determine if we need to do the zero cross workaround on this device. +// Three criteria are used. All three must be true. +// 1. Are the bucks enabled? +// 2. Is the chip rev appropriate for the workaround? +// 3. Has a timer been allocated to do the workaround? +// 4. Are certain peripherals powered up? +// +// Saves the bitmask to the global g_buckZX_chk. +// Bitmask bits are defined as: CHKBUCKZX_BUCKS, CHKBUCKZX_REV, CHKBUCKZX_TIMER. +// +// Returns true if all criteria are met, false otherwise. +// g_buckZX_chk can be probed to determine which criteria passed or failed. +// +//***************************************************************************** +static bool +buckZX_chk(void) +{ + uint32_t ui32SupplySrc; + + // + // Is this chip rev appropriate to do the workaround? + // + g_buckZX_chk = AM_BFM(MCUCTRL, CHIPREV, REVMAJ) == AM_REG_MCUCTRL_CHIPREV_REVMAJ_B ? + CHKBUCKZX_REV : 0x0; + + // + // Has a timer been configured to handle the workaround? + // + g_buckZX_chk |= ( g_ui32BuckTimer - 1 ) <= BUCK_TIMER_MAX ? + CHKBUCKZX_TIMER : 0x0; + + // + // Are either or both of the bucks actually enabled? + // + ui32SupplySrc = AM_REG(PWRCTRL, SUPPLYSRC); + + g_buckZX_chk |= (ui32SupplySrc & + (AM_REG_PWRCTRL_SUPPLYSRC_COREBUCKEN_M | + AM_REG_PWRCTRL_SUPPLYSRC_MEMBUCKEN_M) ) ? + CHKBUCKZX_BUCKS : 0x0; + + // + // Finally, if any peripheral is already powered up, we don't need to do the + // ZX workaround because in this case the bucks remain in active mode. + // + ui32SupplySrc = AM_REG(PWRCTRL, DEVICEEN); + + g_buckZX_chk |= ( ui32SupplySrc & + (AM_REG_PWRCTRL_DEVICEEN_PDM_M | + AM_REG_PWRCTRL_DEVICEEN_UART1_M | + AM_REG_PWRCTRL_DEVICEEN_UART0_M | + AM_REG_PWRCTRL_DEVICEEN_IO_MASTER5_M | + AM_REG_PWRCTRL_DEVICEEN_IO_MASTER4_M | + AM_REG_PWRCTRL_DEVICEEN_IO_MASTER3_M | + AM_REG_PWRCTRL_DEVICEEN_IO_MASTER2_M | + AM_REG_PWRCTRL_DEVICEEN_IO_MASTER1_M | + AM_REG_PWRCTRL_DEVICEEN_IO_MASTER0_M | + AM_REG_PWRCTRL_DEVICEEN_IO_SLAVE_M) ) ? + 0x0 : CHKBUCKZX_DEVEN; + + // + // If all 4 criteria were met, we're good to do the workaround. + // + return ( g_buckZX_chk == + (CHKBUCKZX_BUCKS | CHKBUCKZX_REV | + CHKBUCKZX_TIMER | CHKBUCKZX_DEVEN) ) ? true : false; +} + +//***************************************************************************** +// +// Set the buck zero cross settings to the values given. +// +// ui32Flags, one or more of the following: +// SETBUCKZX_USE_PROVIDED_SETTINGS - Use the values provided in the parameters +// to set the trim value(s). +// SETBUCKZX_USE_SAVED_SETTINGS - Use the values that were previously saved +// to set the trim value(s). +// SETBUCKZX_SAVE_CURR_SETTINGS - Save the current trim values before +// setting the new ones. +// SETBUCKZX_RESTORE_CORE_ONLY - Restore the Core trim and save the current +// value of the core buck trim iff +// SETBUCKZX_SAVE_CURR_SETTINGS is set. +// SETBUCKZX_RESTORE_MEM_ONLY - Restore the Mem trim and save the current +// value of the mem buck trim iff +// SETBUCKZX_SAVE_CURR_SETTINGS is set. +// SETBUCKZX_RESTORE_BOTH - Restore both buck trims and save the +// current value of both iff +// SETBUCKZX_SAVE_CURR_SETTINGS is set. +// +//***************************************************************************** +#define SETBUCKZX_USE_PROVIDED_SETTINGS 0x01 +#define SETBUCKZX_USE_SAVED_SETTINGS 0x02 +#define SETBUCKZX_SAVE_CURR_SETTINGS 0x04 +#define SETBUCKZX_RESTORE_CORE_ONLY 0x10 +#define SETBUCKZX_RESTORE_MEM_ONLY 0x20 +#define SETBUCKZX_RESTORE_BOTH ( SETBUCKZX_RESTORE_CORE_ONLY | \ + SETBUCKZX_RESTORE_MEM_ONLY ) +static void +setBuckZX(uint32_t ui32CoreBuckZX, uint32_t ui32MemBuckZX, uint32_t ui32Flags) +{ + uint32_t ui32SaveCore, ui32SaveMem, ui32NewCore, ui32NewMem; + bool bDoRestore = false; + + // + // Begin critical section. + // + AM_CRITICAL_BEGIN_ASM + + // + // Get the current zero cross trim values. + // + ui32SaveCore = AM_BFR(MCUCTRL, BUCK3, COREBUCKZXTRIM); + ui32SaveMem = AM_BFR(MCUCTRL, BUCK3, MEMBUCKZXTRIM); + + // + // Determine which values will be restored. + // + if ( ui32Flags & SETBUCKZX_USE_SAVED_SETTINGS ) + { + // + // Use saved settings + // + ui32NewCore = g_ui32SaveCoreBuckZX; + ui32NewMem = g_ui32SaveMemBuckZX; + bDoRestore = true; + } + else if ( ui32Flags & SETBUCKZX_USE_PROVIDED_SETTINGS ) + { + // + // Use settings provided in the call parameters + // + ui32NewCore = ui32CoreBuckZX; + ui32NewMem = ui32MemBuckZX; + bDoRestore = true; + } + + // + // Restore the buck Core and Mem trim registers. + // + if ( bDoRestore ) + { + if ( ui32Flags & SETBUCKZX_RESTORE_CORE_ONLY ) + { + AM_BFW(MCUCTRL, BUCK3, COREBUCKZXTRIM, ui32NewCore); + } + + if ( ui32Flags & SETBUCKZX_RESTORE_MEM_ONLY ) + { + AM_BFW(MCUCTRL, BUCK3, MEMBUCKZXTRIM, ui32NewMem); + } + } + + if ( ui32Flags & SETBUCKZX_SAVE_CURR_SETTINGS ) + { + // + // Save off the zero cross values as read on entry to the function. + // + if ( ui32Flags & SETBUCKZX_RESTORE_CORE_ONLY ) + { + g_ui32SaveCoreBuckZX = ui32SaveCore; + } + + if ( ui32Flags & SETBUCKZX_RESTORE_MEM_ONLY ) + { + g_ui32SaveMemBuckZX = ui32SaveMem; + } + } + + // + // Done with critical section. + // + AM_CRITICAL_END_ASM +} + +//***************************************************************************** +// +//! @brief Place the core into sleep or deepsleep. +//! +//! @param bSleepDeep - False for Normal or True Deep sleep. +//! +//! This function puts the MCU to sleep or deepsleep depending on bSleepDeep. +//! +//! Valid values for bSleepDeep are: +//! +//! AM_HAL_SYSCTRL_SLEEP_NORMAL +//! AM_HAL_SYSCTRL_SLEEP_DEEP +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_sysctrl_sleep(bool bSleepDeep) +{ + uint32_t ui32Critical; +// uint32_t ui32DebugGpioSleep = g_ui32DebugGpioSleep - 1; + bool bBuckZX_chk; + volatile uint32_t ui32BuckTimer; + + // + // Disable interrupts and save the previous interrupt state. + // + ui32Critical = am_hal_interrupt_master_disable(); + + // + // If the user selected DEEPSLEEP and the TPIU is off, attempt to enter + // DEEP SLEEP. + // + if ((bSleepDeep == AM_HAL_SYSCTRL_SLEEP_DEEP) && + (AM_BFM(MCUCTRL, TPIUCTRL, ENABLE) == AM_REG_MCUCTRL_TPIUCTRL_ENABLE_DIS)) + { + // + // Prepare the core for deepsleep (write 1 to the DEEPSLEEP bit). + // + AM_BFW(SYSCTRL, SCR, SLEEPDEEP, 1); + + // + // Check if special buck handling is needed + // + bBuckZX_chk = buckZX_chk(); + + if ( bBuckZX_chk ) + { + ui32BuckTimer = g_ui32BuckTimer - 1; + + // + // Before going to sleep, clear the buck timers. + // This will also handle the case where we're going back to + // sleep before the buck sequence has even completed. + // + am_hal_ctimer_clear(ui32BuckTimer, AM_HAL_CTIMER_BOTH); + + // + // Set CMPR0 of both timerA and timerB to the period value + // + #define TIMER_PERIOD_BUCKS 1 + am_hal_ctimer_period_set(ui32BuckTimer, + AM_HAL_CTIMER_BOTH, + TIMER_PERIOD_BUCKS | + (TIMER_PERIOD_BUCKS << 16), + 0); + + // + // Disable bucks before going to sleep. + // + am_hal_pwrctrl_bucks_disable(); + } + + // + // Execute the sleep instruction. + // + AM_ASM_WFI; + + // + // Return from sleep + // + if ( bBuckZX_chk ) + { + // + // Adjust the core and mem trims + // + setBuckZX(COREZXVALUE, MEMZXVALUE, + SETBUCKZX_USE_PROVIDED_SETTINGS | + SETBUCKZX_RESTORE_BOTH ); + + // + // Delay for 2us before enabling bucks. + // + am_hal_flash_delay( FLASH_CYCLES_US(2) ); + + // + // Turn on the bucks + // + am_hal_pwrctrl_bucks_enable(); + + // + // Get the actual timer number + // + ui32BuckTimer = g_ui32BuckTimer - 1; + + // + // Initialize the complete flag + // + g_bBuckRestoreComplete = false; + + // + // Initialize the input flags + // + g_ui32BuckInputs = 0; + + // + // Delay for 5us to make sure we're receiving clean buck signals. + // + am_hal_flash_delay( FLASH_CYCLES_US(5) ); + + // + // Start timers (set the enable bit, clear the clear bit) + // + am_hal_ctimer_start(ui32BuckTimer, AM_HAL_CTIMER_BOTH); + } + else + { + // + // Since we're not doing anything, we're done, so set the done flag. + // + g_bBuckRestoreComplete = true; + } + } + else + { + // + // Prepare the core for normal sleep (write 0 to the DEEPSLEEP bit). + // + AM_BFW(SYSCTRL, SCR, SLEEPDEEP, 0); + + // + // Go to sleep. + // + AM_ASM_WFI; + } + + // + // Restore the interrupt state. + // + am_hal_interrupt_master_set(ui32Critical); +} + +//***************************************************************************** +// +//! @brief Enable the floating point module. +//! +//! Call this function to enable the ARM hardware floating point module. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_sysctrl_fpu_enable(void) +{ + // + // Enable access to the FPU in both privileged and user modes. + // NOTE: Write 0s to all reserved fields in this register. + // + AM_REG(SYSCTRL, CPACR) = (AM_REG_SYSCTRL_CPACR_CP11(0x3) | + AM_REG_SYSCTRL_CPACR_CP10(0x3)); +} + +//***************************************************************************** +// +//! @brief Disable the floating point module. +//! +//! Call this function to disable the ARM hardware floating point module. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_sysctrl_fpu_disable(void) +{ + // + // Disable access to the FPU in both privileged and user modes. + // NOTE: Write 0s to all reserved fields in this register. + // + AM_REG(SYSCTRL, CPACR) = 0x00000000 & + ~(AM_REG_SYSCTRL_CPACR_CP11(0x3) | + AM_REG_SYSCTRL_CPACR_CP10(0x3)); +} + +//***************************************************************************** +// +//! @brief Enable stacking of FPU registers on exception entry. +//! +//! @param bLazy - Set to "true" to enable "lazy stacking". +//! +//! This function allows the core to save floating-point information to the +//! stack on exception entry. Setting the bLazy option enables "lazy stacking" +//! for interrupt handlers. Normally, mixing floating-point code and interrupt +//! driven routines causes increased interrupt latency, because the core must +//! save extra information to the stack upon exception entry. With the lazy +//! stacking option enabled, the core will skip the saving of floating-point +//! registers when possible, reducing average interrupt latency. +//! +//! @note This function should be called before the floating-point module is +//! used in interrupt-driven code. If it is not called, the core will not have +//! any way to save context information for floating-point variables on +//! exception entry. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_sysctrl_fpu_stacking_enable(bool bLazy) +{ + if ( bLazy ) + { + // + // Enable automatic saving of FPU registers on exception entry, using lazy + // context saving. + // + AM_REG(SYSCTRL, FPCCR) |= (AM_REG_SYSCTRL_FPCCR_ASPEN(0x1) | + AM_REG_SYSCTRL_FPCCR_LSPEN(0x1)); + } + else + { + // + // Enable automatic saving of FPU registers on exception entry. + // + AM_REG(SYSCTRL, FPCCR) |= AM_REG_SYSCTRL_FPCCR_ASPEN(0x1); + } +} + +//***************************************************************************** +// +//! @brief Disable FPU register stacking on exception entry. +//! +//! This function disables all stacking of floating point registers for +//! interrupt handlers. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_sysctrl_fpu_stacking_disable(void) +{ + // + // Enable automatic saving of FPU registers on exception entry, using lazy + // context saving. + // + AM_REG(SYSCTRL, FPCCR) &= ~(AM_REG_SYSCTRL_FPCCR_ASPEN(0x1) | + AM_REG_SYSCTRL_FPCCR_LSPEN(0x1)); +} + +//***************************************************************************** +// +//! @brief Issue a system wide reset using the AIRCR bit in the M4 system ctrl. +//! +//! This function issues a system wide reset (Apollo POR level reset). +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_sysctrl_aircr_reset(void) +{ + // + // Set the system reset bit in the AIRCR register + // + AM_REG(SYSCTRL, AIRCR) = AM_REG_SYSCTRL_AIRCR_VECTKEY(0x5FA) | + AM_REG_SYSCTRL_AIRCR_SYSRESETREQ(1); +} + +//***************************************************************************** +// +//! @brief Buck CTimer ISR initializer. +//! +//! @param ui32BuckTimerNumber - Timer number to be used for handling the buck. +//! Must be 0-3. +//! +//! If called with an invalid timer (that is, not 0 - 3, or greater than +//! BUCK_TIMER_MAX), then the workaround will not be enabled. +//! +//! Instead, the bucks will be initialized with a value that will avoid the +//! issues described in the Errata (ERR019). However, this will cause a +//! less efficient energy usage condtion. +//! +//! @return 0. +// +//***************************************************************************** +uint32_t +am_hal_sysctrl_buck_ctimer_isr_init(uint32_t ui32BuckTimerNumber) +{ + uint32_t ui32RetVal = 0; + + // + // Initialize the input flags + // + g_ui32BuckInputs = 0; + + // + // Initialize operation complete flag + // + g_bBuckRestoreComplete = false; + + // + // Initialize to assume there is no valid timer. + // + g_ui32BuckTimer = 0; + + if ( ui32BuckTimerNumber > BUCK_TIMER_MAX ) + { + if ( ( ui32BuckTimerNumber & 0xFFFF0000 ) == + AM_HAL_SYSCTRL_BUCK_CTIMER_ZX_CONSTANT ) + { + // + // The caller is asking for the hard option, which changes the + // settings to the more noise-immune, if less efficient, settings. + // While we're at it, go ahead and save off the current settings. + // + if ( (ui32BuckTimerNumber & 0x0000FFFF) == 0 ) + { + setBuckZX(COREZXVALUE, MEMZXVALUE, + SETBUCKZX_USE_PROVIDED_SETTINGS | + SETBUCKZX_SAVE_CURR_SETTINGS | + SETBUCKZX_RESTORE_BOTH ); + } + else + { + uint32_t ui32Core, ui32Mem; + + // + // Use the setting provided in the parameter. + // + ui32Core = (((ui32BuckTimerNumber & 0x001F) >> 0) - 1) & 0xF; + ui32Mem = (((ui32BuckTimerNumber & 0x1F00) >> 8) - 1) & 0xF; + + setBuckZX(ui32Core, ui32Mem, + SETBUCKZX_USE_PROVIDED_SETTINGS | + SETBUCKZX_SAVE_CURR_SETTINGS | + SETBUCKZX_RESTORE_BOTH ); + } + } + } + else + { + // + // Save off the current trim settings (but don't change any settings). + // + setBuckZX(0, 0, SETBUCKZX_SAVE_CURR_SETTINGS | SETBUCKZX_RESTORE_BOTH); + + // + // The timer number will be maintained as (n + 1). Therefore, a value + // of 0 saved in the global is an invalid timer. 1=timer0, 2=timer1... + // + g_ui32BuckTimer = ui32BuckTimerNumber + 1; + + // + // Register the timer ISRs + // + am_hal_ctimer_int_register( AM_HAL_CTIMER_INT_TIMERA0C0 << + (ui32BuckTimerNumber * 2), + am_hal_sysctrl_buckA_ctimer_isr ); + + am_hal_ctimer_int_register( AM_HAL_CTIMER_INT_TIMERB0C0 << + (ui32BuckTimerNumber * 2), + am_hal_sysctrl_buckB_ctimer_isr ); + + // + // Determine which timer input (A or B) is core buck and which is mem + // buck based on the timer number. + // For CTIMER 0 & 1: Timer A is mem buck, Timer B is core buck + // For CTIMER 2 & 3: Timer A is core buck, Timer B is mem buck + // + if ( (ui32BuckTimerNumber == 0) || (ui32BuckTimerNumber == 1) ) + { + // + // Indicate that TimerB is core buck. + // + g_ui32CoreBuck = COREBUCK_TIMERB; + } + else + { + // + // Indicate that TimerA is core buck + // + g_ui32CoreBuck = COREBUCK_TIMERA; + } + + // + // Clear and configure the timers + // + am_hal_ctimer_clear(ui32BuckTimerNumber, AM_HAL_CTIMER_BOTH); + + am_hal_ctimer_config(ui32BuckTimerNumber, + (am_hal_ctimer_config_t*)&g_sBuckTimer); + + // + // Enable the interrupts for timers A and B + // + am_hal_ctimer_int_enable( (AM_HAL_CTIMER_INT_TIMERA0C0 | + AM_HAL_CTIMER_INT_TIMERB0C0 ) << + (ui32BuckTimerNumber * 2) ); + + // + // Enable the timer interrupt in the NVIC. + // + am_hal_interrupt_enable(AM_HAL_INTERRUPT_CTIMER); + } + + return ui32RetVal; +} + +//***************************************************************************** +// +// Get buck update complete status. +// +//***************************************************************************** +bool +am_hal_sysctrl_buck_update_complete(void) +{ + return g_bBuckRestoreComplete; +} + +//***************************************************************************** +// +// Buck CTIMER ISR (for handling buck switching via TimerA). +// +// Note: This handler assumes that the interrupt is cleared in am_ctimer_isr(). +// +//***************************************************************************** +static void +am_hal_sysctrl_buckA_ctimer_isr(void) +{ + volatile uint32_t ui32BuckTimer = g_ui32BuckTimer - 1; + + // + // Begin critical section. + // Although a relatively long time, the following 2us delay is critically + // timed for re-trimming the buck and thus cannot be extended. Therefore, + // we must keep it inside the critical section. + // + AM_CRITICAL_BEGIN_ASM + + // + // Delay for 2us. + // + am_hal_flash_delay( FLASH_CYCLES_US(2) ); + + // + // Determine which buck (core or mem) needs to be updated. + // + if ( g_ui32CoreBuck == COREBUCK_TIMERA ) + { + // + // Timer A buck signal is the CORE buck. + // Restore the core buck. + // + setBuckZX(0, 0, SETBUCKZX_RESTORE_CORE_ONLY | + SETBUCKZX_USE_SAVED_SETTINGS ); + } + else + { + // + // Timer A buck signal is the MEM buck. + // Restore the mem buck. + // + setBuckZX(0, 0, SETBUCKZX_RESTORE_MEM_ONLY | + SETBUCKZX_USE_SAVED_SETTINGS ); + } + + g_ui32BuckInputs |= 0x1; + + if ( g_ui32BuckInputs == 0x3 ) + { + g_bBuckRestoreComplete = true; + g_ui32BuckInputs = 0; + } + + // + // End critical section. + // + AM_CRITICAL_END_ASM +} + +//***************************************************************************** +// +// Buck CTIMER ISR (for handling buck switching via TimerB). +// +// Note: This handler assumes that the interrupt is cleared in am_ctimer_isr(). +// +//***************************************************************************** +static void +am_hal_sysctrl_buckB_ctimer_isr(void) +{ + volatile uint32_t ui32BuckTimer = g_ui32BuckTimer - 1; + + // + // Begin critical section. + // Although a relatively long time, the following 2us delay is critically + // timed for re-trimming the buck and thus cannot be extended. Therefore, + // we must keep it inside the critical section. + // + AM_CRITICAL_BEGIN_ASM + + // + // Delay for 2us. + // + am_hal_flash_delay( FLASH_CYCLES_US(2) ); + + // + // Determine which buck (core or mem) needs to be updated. + // + if ( g_ui32CoreBuck == COREBUCK_TIMERB ) + { + // + // Timer B buck signal is the CORE buck. + // Restore the core buck. + // + setBuckZX(0, 0, SETBUCKZX_RESTORE_CORE_ONLY | + SETBUCKZX_USE_SAVED_SETTINGS ); + } + else + { + // + // Timer B buck signal is the MEM buck. + // Restore the mem buck. + // + setBuckZX(0, 0, SETBUCKZX_RESTORE_MEM_ONLY | + SETBUCKZX_USE_SAVED_SETTINGS ); + } + + g_ui32BuckInputs |= 0x2; + + if ( g_ui32BuckInputs == 0x3 ) + { + g_bBuckRestoreComplete = true; + g_ui32BuckInputs = 0; + } + + // + // End critical section. + // + AM_CRITICAL_END_ASM +} + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_sysctrl.h b/bsp/apollo2/libraries/drivers/hal/am_hal_sysctrl.h new file mode 100644 index 0000000000..34c72b4173 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_sysctrl.h @@ -0,0 +1,119 @@ +//***************************************************************************** +// +//! am_hal_sysctrl.h +//! @file +//! +//! @brief Functions for interfacing with the M4F system control registers +//! +//! @addtogroup sysctrl2 System Control (SYSCTRL) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_SYSCTRL_H +#define AM_HAL_SYSCTRL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Definitions for sleep mode parameter +// +//***************************************************************************** +#define AM_HAL_SYSCTRL_SLEEP_DEEP true +#define AM_HAL_SYSCTRL_SLEEP_NORMAL false + +//***************************************************************************** +// +// Parameters for am_hal_sysctrl_buck_ctimer_isr_init() +// +//***************************************************************************** +// +// Define the maximum valid timer number +// +#define BUCK_TIMER_MAX (AM_HAL_CTIMER_TIMERS_NUM - 1) + +// +// Define the valid timer numbers +// +#define AM_HAL_SYSCTRL_BUCK_CTIMER_TIMER0 0 +#define AM_HAL_SYSCTRL_BUCK_CTIMER_TIMER1 1 +#define AM_HAL_SYSCTRL_BUCK_CTIMER_TIMER2 2 +#define AM_HAL_SYSCTRL_BUCK_CTIMER_TIMER3 3 + +// +// The following is an invalid timer number. If used, it is the caller telling +// the HAL to use the "Hard Option", which applies a constant value to the zero +// cross. The applied value is more noise immune, if less energy efficent. +// +#define AM_HAL_SYSCTRL_BUCK_CTIMER_ZX_CONSTANT 0x01000000 // No timer, apply a constant value + +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern void am_hal_sysctrl_sleep(bool bSleepDeep); +extern void am_hal_sysctrl_fpu_enable(void); +extern void am_hal_sysctrl_fpu_disable(void); +extern void am_hal_sysctrl_fpu_stacking_enable(bool bLazy); +extern void am_hal_sysctrl_fpu_stacking_disable(void); +extern void am_hal_sysctrl_aircr_reset(void); + +// +// Apollo2 zero-cross buck/ctimer related functions +// +extern uint32_t am_hal_sysctrl_buck_ctimer_isr_init(uint32_t ui32BuckTimerNumber); +extern bool am_hal_sysctrl_buck_update_complete(void); + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_SYSCTRL_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** + diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_systick.c b/bsp/apollo2/libraries/drivers/hal/am_hal_systick.c new file mode 100644 index 0000000000..3654910495 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_systick.c @@ -0,0 +1,453 @@ +//***************************************************************************** +// +// am_hal_systick.c +//! @file +//! +//! @brief Functions for interfacing with the SYSTICK +//! +//! @addtogroup systick2 System Timer (SYSTICK) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + + +//***************************************************************************** +// +// Macro definitions +// +//***************************************************************************** +#define SYSTICK_MAX_TICKS ((1 << 24)-1) +#define MAX_U32 (0xffffffff) + +//***************************************************************************** +// +//! @brief Start the SYSTICK. +//! +//! This function starts the systick timer. +//! +//! @note This timer does not run in deep-sleep mode as it runs from the core +//! clock, which is gated in deep-sleep. If a timer is needed in deep-sleep use +//! one of the ctimers instead. Also to note is this timer will consume higher +//! power than the ctimers. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_systick_start(void) +{ + // + // Start the systick timer. + // + AM_REG(SYSTICK, SYSTCSR) |= AM_REG_SYSTICK_SYSTCSR_ENABLE_M; +} + +//***************************************************************************** +// +//! @brief Stop the SYSTICK. +//! +//! This function stops the systick timer. +//! +//! @note This timer does not run in deep-sleep mode as it runs from the core +//! clock, which is gated in deep-sleep. If a timer is needed in deep-sleep use +//! one of the ctimers instead. Also to note is this timer will consume higher +//! power than the ctimers. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_systick_stop(void) +{ + // + // Stop the systick timer. + // + AM_REG(SYSTICK, SYSTCSR) &= ~AM_REG_SYSTICK_SYSTCSR_ENABLE_M; +} + +//***************************************************************************** +// +//! @brief Enable the interrupt in the SYSTICK. +//! +//! This function enables the interupt in the systick timer. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_systick_int_enable(void) +{ + // + // Enable the systick timer interrupt. + // + AM_REG(SYSTICK, SYSTCSR) |= AM_REG_SYSTICK_SYSTCSR_TICKINT_M; +} + +//***************************************************************************** +// +//! @brief Disable the interrupt in the SYSTICK. +//! +//! This function disables the interupt in the systick timer. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_systick_int_disable(void) +{ + // + // Disable the systick timer interrupt. + // + AM_REG(SYSTICK, SYSTCSR) &= ~AM_REG_SYSTICK_SYSTCSR_TICKINT_M; +} + +//***************************************************************************** +// +//! @brief Reads the interrupt status. +//! +//! This function reads the interrupt status in the systick timer. +//! +//! @return the interrupt status. +// +//***************************************************************************** +uint32_t +am_hal_systick_int_status_get(void) +{ + // + // Return the systick timer interrupt status. + // + return AM_REG(SYSTICK, SYSTCSR) & AM_REG_SYSTICK_SYSTCSR_COUNTFLAG_M; +} + +//***************************************************************************** +// +//! @brief Reset the interrupt in the SYSTICK. +//! +//! This function resets the systick timer by clearing out the configuration +//! register. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_systick_reset(void) +{ + // + // Reset the systick timer interrupt. + // + AM_REG(SYSTICK, SYSTCSR) = 0x0; +} + +//***************************************************************************** +// +//! @brief Load the value into the SYSTICK. +//! +//! @param ui32LoadVal the desired load value for the systick. Maximum value is +//! 0x00FF.FFFF. +//! +//! This function loads the desired value into the systick timer. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_systick_load(uint32_t ui32LoadVal) +{ + // + // Write the reload register. + // + AM_REG(SYSTICK, SYSTRVR) = ui32LoadVal; +} + +//***************************************************************************** +// +//! @brief Get the current count value in the SYSTICK. +//! +//! This function gets the current count value in the systick timer. +//! +//! @return Current count value. +// +//***************************************************************************** +uint32_t +am_hal_systick_count(void) +{ + // + // Return the current systick timer count value. + // + return AM_REG(SYSTICK, SYSTCVR); +} + +//***************************************************************************** +// +//! @brief Wait the specified number of ticks. +//! +//! This function delays for the given number of SysTick ticks. +//! +//! @note If the SysTick timer is being used elsewhere, it will be corrupted +//! by calling this function. +//! +//! @return 0 if successful. +// +//***************************************************************************** +uint32_t +am_hal_systick_wait_ticks(uint32_t u32Ticks) +{ + + if ( u32Ticks == 0 ) + { + u32Ticks++; // Make sure we get the COUNTFLAG + } + + // + // The proper SysTick initialization sequence is: (p 4-36 of the M4 UG). + // 1. Program reload value + // 2. Clear current value + // 3. Program CSR + // + // Set the reload value to the required number of ticks. + // + AM_REG(SYSTICK, SYSTRVR) = u32Ticks; + + // + // Clear the current count. + // + AM_REG(SYSTICK, SYSTCVR) = 0x0; + + // + // Set to use the processor clock, but don't cause an exception (we'll poll). + // + AM_REG(SYSTICK, SYSTCSR) = AM_REG_SYSTICK_SYSTCSR_ENABLE_M; + + // + // Poll till done + // + while ( !(AM_REG(SYSTICK, SYSTCSR) & AM_REG_SYSTICK_SYSTCSR_COUNTFLAG_M) ); + + // + // And disable systick before exiting. + // + AM_REG(SYSTICK, SYSTCSR) = 0; + + return 0; +} + +//***************************************************************************** +// +//! @brief Delay the specified number of microseconds. +//! +//! This function will use the SysTick timer to delay until the specified +//! number of microseconds have elapsed. It uses the processor clocks and +//! takes into account the current CORESEL setting. +//! +//! @note If the SysTick timer is being used elsewhere, it will be corrupted +//! by calling this function. +//! +//! @return Total number of SysTick ticks delayed. +// +//***************************************************************************** +uint32_t +am_hal_systick_delay_us(uint32_t u32NumUs) +{ + uint32_t u32ClkFreq, u32nLoops, u32Ticks, uRet; + uint32_t u32CoreSel = AM_BFR(CLKGEN, CCTRL, CORESEL); + + u32nLoops = 1; + switch (u32CoreSel) + { + // + // We need to compute the required number of ticks. To do so and to + // minimize divide operations, we'll use the following equation: + // u32Ticks = (u32NumUs * HFCR_EXACT)/1000000 + // = (u32NumUs * (HFCR_EXACT * 1024)/1000000) / 1024 + // The values for the variable u32ClkFreq are computed as follows: + // u32ClkFreq = (24390200 * 1024) / ((clksel+1)*1000000); + // (and we'll do the remaining divide by 1024, using a shift, later). + // + case 0: + u32ClkFreq = 24975; + if ( u32NumUs > ((SYSTICK_MAX_TICKS / 24975)*1024) ) + { + u32nLoops = (u32NumUs / ((SYSTICK_MAX_TICKS / 24975)*1024)) + 1; + u32NumUs /= u32nLoops; + } + if ( u32NumUs > (MAX_U32 / 24975) ) + { + u32Ticks = (u32NumUs >> 10) * u32ClkFreq; + } + else + { + u32Ticks = (u32NumUs * u32ClkFreq) >> 10; + } + break; + case 1: + u32ClkFreq = 12487; + if ( u32NumUs > ((SYSTICK_MAX_TICKS / 12487)*1024) ) + { + u32nLoops = (u32NumUs / ((SYSTICK_MAX_TICKS / 12487)*1024)) + 1; + u32NumUs /= u32nLoops; + } + if ( u32NumUs > (MAX_U32 / 12487) ) + { + u32Ticks = (u32NumUs >> 10) * u32ClkFreq; + } + else + { + u32Ticks = (u32NumUs * u32ClkFreq) >> 10; + } + break; + case 2: + u32ClkFreq = 8325; + if ( u32NumUs > ((SYSTICK_MAX_TICKS / 8325)*1024) ) + { + u32nLoops = (u32NumUs / ((SYSTICK_MAX_TICKS / 8325)*1024)) + 1; + u32NumUs /= u32nLoops; + } + if ( u32NumUs > (MAX_U32 / 8325) ) + { + u32Ticks = (u32NumUs >> 10) * u32ClkFreq; + } + else + { + u32Ticks = (u32NumUs * u32ClkFreq) >> 10; + } + break; + case 3: + u32ClkFreq = 6243; + if ( u32NumUs > ((SYSTICK_MAX_TICKS / 6243)*1024) ) + { + u32nLoops = (u32NumUs / ((SYSTICK_MAX_TICKS / 6243)*1024)) + 1; + u32NumUs /= u32nLoops; + } + if ( u32NumUs > (MAX_U32 / 6243) ) + { + u32Ticks = (u32NumUs >> 10) * u32ClkFreq; + } + else + { + u32Ticks = (u32NumUs * u32ClkFreq) >> 10; + } + break; + case 4: + u32ClkFreq = 4995; + if ( u32NumUs > ((SYSTICK_MAX_TICKS / 4995)*1024) ) + { + u32nLoops = (u32NumUs / ((SYSTICK_MAX_TICKS / 4995)*1024)) + 1; + u32NumUs /= u32nLoops; + } + if ( u32NumUs > (MAX_U32 / 4995) ) + { + u32Ticks = (u32NumUs >> 10) * u32ClkFreq; + } + else + { + u32Ticks = (u32NumUs * u32ClkFreq) >> 10; + } + break; + case 5: + u32ClkFreq = 4162; + if ( u32NumUs > ((SYSTICK_MAX_TICKS / 4162)*1024) ) + { + u32nLoops = (u32NumUs / ((SYSTICK_MAX_TICKS / 4162)*1024)) + 1; + u32NumUs /= u32nLoops; + } + if ( u32NumUs > (MAX_U32 / 4162) ) + { + u32Ticks = (u32NumUs >> 10) * u32ClkFreq; + } + else + { + u32Ticks = (u32NumUs * u32ClkFreq) >> 10; + } + break; + case 6: + u32ClkFreq = 3567; + if ( u32NumUs > ((SYSTICK_MAX_TICKS / 3567)*1024) ) + { + u32nLoops = (u32NumUs / ((SYSTICK_MAX_TICKS / 3567)*1024)) + 1; + u32NumUs /= u32nLoops; + } + if ( u32NumUs > (MAX_U32 / 3567) ) + { + u32Ticks = (u32NumUs >> 10) * u32ClkFreq; + } + else + { + u32Ticks = (u32NumUs * u32ClkFreq) >> 10; + } + break; + case 7: + u32ClkFreq = 3121; + if ( u32NumUs > ((SYSTICK_MAX_TICKS / 3121)*1024) ) + { + u32nLoops = (u32NumUs / ((SYSTICK_MAX_TICKS / 3121)*1024)) + 1; + u32NumUs /= u32nLoops; + } + if ( u32NumUs > (MAX_U32 / 3121) ) + { + u32Ticks = (u32NumUs >> 10) * u32ClkFreq; + } + else + { + u32Ticks = (u32NumUs * u32ClkFreq) >> 10; + } + break; + default: + u32Ticks = 1; + break; + } // switch() + + uRet = u32Ticks * u32nLoops; + while ( u32nLoops-- ) + { + am_hal_systick_wait_ticks(u32Ticks); + } + + return uRet; +} + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_systick.h b/bsp/apollo2/libraries/drivers/hal/am_hal_systick.h new file mode 100644 index 0000000000..bd5e576938 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_systick.h @@ -0,0 +1,83 @@ +//***************************************************************************** +// +// am_hal_systick.h +//! @file +//! +//! @brief Functions for accessing and configuring the SYSTICK. +//! +//! @addtogroup systick2 System Timer (SYSTICK) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_SYSTICK_H +#define AM_HAL_SYSTICK_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern void am_hal_systick_start(void); +extern void am_hal_systick_stop(void); +extern void am_hal_systick_int_enable(void); +extern void am_hal_systick_int_disable(void); +extern uint32_t am_hal_systick_int_status_get(void); +extern void am_hal_systick_reset(void); +extern void am_hal_systick_load(uint32_t ui32LoadVal); +extern uint32_t am_hal_systick_count(void); +extern uint32_t am_hal_systick_wait_ticks(uint32_t u32Ticks); +extern uint32_t am_hal_systick_delay_us(uint32_t u32NumUs); + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_SYSTICK_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_tpiu.c b/bsp/apollo2/libraries/drivers/hal/am_hal_tpiu.c new file mode 100644 index 0000000000..722f22fa13 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_tpiu.c @@ -0,0 +1,381 @@ +//***************************************************************************** +// +// am_hal_tpiu.c +//! @file +//! +//! @brief Support functions for the ARM TPIU module +//! +//! Provides support functions for configuring the ARM TPIU module +//! +//! @addtogroup tpiu2 Trace Port Interface Unit (TPIU) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +//! @brief Enable the clock to the TPIU module. +//! +//! This function enables the clock to the TPIU module. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_tpiu_clock_enable(void) +{ + // + // Enable the TPIU clock + // + AM_REG(MCUCTRL, TPIUCTRL) |= AM_REG_MCUCTRL_TPIUCTRL_ENABLE_M; +} + +//***************************************************************************** +// +//! @brief Disable the clock to the TPIU module. +//! +//! This function disables the clock to the TPIU module. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_tpiu_clock_disable(void) +{ + // + // Disable the TPIU clock + // + AM_REG(MCUCTRL, TPIUCTRL) &= ~AM_REG_MCUCTRL_TPIUCTRL_ENABLE_M; +} + +//***************************************************************************** +// +//! @brief Set the output port width of the TPIU +//! +//! @param ui32PortWidth - The desired port width (in bits) +//! +//! This function uses the TPIU_CSPSR register to set the desired output port +//! width of the TPIU. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_tpiu_port_width_set(uint32_t ui32PortWidth) +{ + AM_REG(TPIU, CSPSR) = 1 << (ui32PortWidth - 1); +} + +//***************************************************************************** +// +//! @brief Read the supported_output port width of the TPIU +//! +//! This function uses the \e TPIU_SSPSR register to set the supported output +//! port widths of the TPIU. +//! +//! @return Current width of the TPIU output port +// +//***************************************************************************** +uint32_t +am_hal_tpiu_supported_port_width_get(void) +{ + uint32_t i, ui32WidthValue; + + // + // Read the supported width register. + // + ui32WidthValue = AM_REG(TPIU, SSPSR); + + // + // The register value is encoded in a one-hot format, so the position of + // the single set bit determines the actual width of the port. + // + for (i = 1; i < 32; i++) + { + // + // Check each bit for a '1'. When we find it, our current loop index + // will be equal to the port width. + // + if (ui32WidthValue == (0x1 << (i - 1))) + { + return i; + } + } + + // + // We should never get here, but if we do, just return the smallest + // possible value for a supported trace port width. + // + return 1; +} + +//***************************************************************************** +// +//! @brief Read the output port width of the TPIU +//! +//! This function uses the \e TPIU_CSPSR register to set the desired output +//! port width of the TPIU. +//! +//! @return Current width of the TPIU output port +// +//***************************************************************************** +uint32_t +am_hal_tpiu_port_width_get(void) +{ + uint32_t ui32Temp; + uint32_t ui32Width; + + ui32Width = 1; + ui32Temp = AM_REG(TPIU, CSPSR); + + while ( !(ui32Temp & 1) ) + { + ui32Temp = ui32Temp >> 1; + ui32Width++; + + if (ui32Width > 32) + { + ui32Width = 0; + break; + } + } + + // + // Current width of the TPIU output port. + // + return ui32Width; +} + +//***************************************************************************** +// +//! @brief Configure the TPIU based on the values in the configuration struct. +//! +//! @param psConfig - pointer to an am_hal_tpiu_config_t structure containing +//! the desired configuration information. +//! +//! This function reads the provided configuration structure, and sets the +//! relevant TPIU registers to achieve the desired configuration. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_tpiu_configure(am_hal_tpiu_config_t *psConfig) +{ + // + // Set the clock freq in the MCUCTRL register. + // + AM_REG(MCUCTRL, TPIUCTRL) |= psConfig->ui32TraceClkIn; + + // + // Set the desired protocol. + // + AM_REG(TPIU, SPPR) = psConfig->ui32PinProtocol; + + // + // Set the parallel port width. This may be redundant if the user has + // selected a serial protocol, but we'll set it anyway. + // + AM_REG(TPIU, CSPSR) = (1 << (psConfig->ui32ParallelPortSize - 1)); + + // + // Set the clock prescaler. + // + AM_REG(TPIU, ACPR) = psConfig->ui32ClockPrescaler; +} + +//***************************************************************************** +// +//! @brief Enables the TPIU +//! +//! This function enables the ARM TPIU by setting the TPIU registers and then +//! enabling the TPIU clock source in MCU control register. +//! +//! @param psConfig - structure for configuration. +//! If ui32SetItmBaud, the other structure members are used to set the +//! TPIU configuration. +//! But for simplicity, ui32SetItmBaud can be set to one of the +//! following, in which case all other structure members are ignored. +//! In this case, the given BAUD rate is based on a div-by-8 HFRC clock. +//! AM_HAL_TPIU_BAUD_57600 +//! AM_HAL_TPIU_BAUD_115200 +//! AM_HAL_TPIU_BAUD_230400 +//! AM_HAL_TPIU_BAUD_460800 +//! AM_HAL_TPIU_BAUD_500000 +//! AM_HAL_TPIU_BAUD_1M +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_tpiu_enable(am_hal_tpiu_config_t *psConfig) +{ + uint32_t ui32HFRC, ui32SWOscaler, ui32ITMbitrate; + + ui32ITMbitrate = psConfig->ui32SetItmBaud; + + // + // TPIU formatter & flush control register. + // + AM_REG(TPIU, FFCR) = 0; + + if ( ui32ITMbitrate ) + { + // + // Set the Current Parallel Port Size (note - only 1 bit can be set). + // + AM_REG(TPIU, CSPSR) = AM_REG_TPIU_CSPSR_CWIDTH_1BIT; + + // + // Use some default assumptions to set the ITM frequency. + // + if ( (ui32ITMbitrate < AM_HAL_TPIU_BAUD_57600 ) || + (ui32ITMbitrate > AM_HAL_TPIU_BAUD_2M ) ) + { + ui32ITMbitrate = AM_HAL_TPIU_BAUD_DEFAULT; + } + + // + // Get the current HFRC frequency. + // + ui32HFRC = am_hal_clkgen_sysclk_get(); + + // + // Compute the SWO scaler value. + // + if ( ui32HFRC != 0xFFFFFFFF ) + { + ui32SWOscaler = ((ui32HFRC / 8) / ui32ITMbitrate) - 1; + } + else + { + ui32SWOscaler = ( (AM_HAL_CLKGEN_FREQ_MAX_HZ / 8) / + AM_HAL_TPIU_BAUD_DEFAULT ) - 1; + } + + // + // Set the scaler value. + // + AM_REG(TPIU, ACPR) = AM_REG_TPIU_ACPR_SWOSCALER(ui32SWOscaler); + + // + // Set for UART mode + // + AM_REG(TPIU, SPPR) = AM_REG_TPIU_SPPR_TXMODE_UART; + + // + // Make sure we are not in test mode (important for proper deep sleep + // operation). + // + AM_REG(TPIU, ITCTRL) = AM_REG_TPIU_ITCTRL_MODE_NORMAL; + + // + // Enable the TPIU clock source in MCU control. + // Set TPIU clock for HFRC/8 (6 or 3 MHz) operation. + // + AM_REGn(MCUCTRL, 0, TPIUCTRL) = + AM_REG_MCUCTRL_TPIUCTRL_CLKSEL_HFRC_DIV_8 | + AM_REG_MCUCTRL_TPIUCTRL_ENABLE_EN; + } + else + { + // + // Set the configuration according to the structure values. + // + + // + // Set the Asynchronous Clock Prescaler Register. + // + AM_REG(TPIU, ACPR) = psConfig->ui32ClockPrescaler; + + // + // Set the Selected Pin Protocol Register. + // e.g. AM_REG_TPIU_SPPR_TXMODE_UART + // + AM_REG(TPIU, SPPR) = psConfig->ui32PinProtocol; + + // + // Set the Current Parallel Port Size (note - only 1 bit can be set). + // This may be redundant if the user has selected a serial protocol, + // but we'll set it anyway. + // + AM_REG(TPIU, CSPSR) = (1 << (psConfig->ui32ParallelPortSize - 1)); + + // + // Set the clock freq in the MCUCTRL register. + // + AM_REG(MCUCTRL, TPIUCTRL) |= psConfig->ui32TraceClkIn; + } + + // + // Wait for 50us for the data to flush out. + // + am_hal_itm_delay_us(50); +} + +//***************************************************************************** +// +//! @brief Disables the TPIU +//! +//! This function disables the ARM TPIU by disabling the TPIU clock source +//! in MCU control register. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_tpiu_disable(void) +{ + // + // Disable the TPIU clock source in MCU control. + // + AM_REG(MCUCTRL, TPIUCTRL) = AM_REG_MCUCTRL_TPIUCTRL_CLKSEL_0MHz | + AM_REG_MCUCTRL_TPIUCTRL_ENABLE_DIS; +} + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_tpiu.h b/bsp/apollo2/libraries/drivers/hal/am_hal_tpiu.h new file mode 100644 index 0000000000..9739034a18 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_tpiu.h @@ -0,0 +1,193 @@ +//***************************************************************************** +// +// am_hal_tpiu.h +//! @file +//! +//! @brief Definitions and structures for working with the TPIU. +//! +//! @addtogroup tpiu2 Trace Port Interface Unit (TPIU) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_TPIU_H +#define AM_HAL_TPIU_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// TPIU bit rate defines. +// +//***************************************************************************** +#define AM_HAL_TPIU_BAUD_57600 (115200 / 2) +#define AM_HAL_TPIU_BAUD_115200 (115200 * 1) +#define AM_HAL_TPIU_BAUD_230400 (115200 * 2) +#define AM_HAL_TPIU_BAUD_460800 (115200 * 4) +#define AM_HAL_TPIU_BAUD_500000 (1000000 / 2) +#define AM_HAL_TPIU_BAUD_1M (1000000 * 1) +#define AM_HAL_TPIU_BAUD_2M (1000000 * 2) +#define AM_HAL_TPIU_BAUD_DEFAULT (AM_HAL_TPIU_BAUD_1M) + +//***************************************************************************** +// +// TPIU register defines. +// +//***************************************************************************** +#define AM_HAL_TPIU_SSPSR 0xE0040000 //! Supported Parallel Port Sizes +#define AM_HAL_TPIU_CSPSR 0xE0040004 //! Current Parallel Port Size +#define AM_HAL_TPIU_ACPR 0xE0040010 //! Asynchronous Clock Prescaler +#define AM_HAL_TPIU_SPPR 0xE00400F0 //! Selected Pin Protocol +#define AM_HAL_TPIU_TYPE 0xE0040FC8 //! TPIU Type + +//***************************************************************************** +// +// TPIU ACPR defines. +// +//***************************************************************************** +#define AM_HAL_TPIU_ACPR_SWOSCALER_M 0x0000FFFF //! SWO baud rate prescalar + +//***************************************************************************** +// +// TPIU_SPPR TXMODE defines. +// +//***************************************************************************** +#define AM_HAL_TPIU_SPPR_PARALLEL 0x00000000 +#define AM_HAL_TPIU_SPPR_MANCHESTER 0x00000001 +#define AM_HAL_TPIU_SPPR_NRZ 0x00000002 + +//***************************************************************************** +// +// TPIU Type defines +// +//***************************************************************************** +#define AM_HAL_TPIU_TYPE_NRZVALID 0x00000800 +#define AM_HAL_TPIU_TYPE_MANCVALID 0x00000400 +#define AM_HAL_TPIU_TYPE_PTINVALID 0x00000200 +#define AM_HAL_TPIU_TYPE_FIFOSZ_M 0x000001C0 + +//***************************************************************************** +// +// TPIU Clock defines +// +//***************************************************************************** +#define AM_HAL_TPIU_TRACECLKIN_6MHZ AM_REG_MCUCTRL_TPIUCTRL_TPIUCLKSEL(0) +#define AM_HAL_TPIU_TRACECLKIN_3MHZ AM_REG_MCUCTRL_TPIUCTRL_TPIUCLKSEL(1) +#define AM_HAL_TPIU_TRACECLKIN_1_5MHZ AM_REG_MCUCTRL_TPIUCTRL_TPIUCLKSEL(2) +#define AM_HAL_TPIU_TRACECLKIN_750KHZ AM_REG_MCUCTRL_TPIUCTRL_TPIUCLKSEL(3) + +//***************************************************************************** +// +//! @brief Structure used for configuring the TPIU +// +//***************************************************************************** +typedef struct +{ + // + // If ui32SetItmBaud is non-zero, the ITM frequency is set to the given + // frequency, and is based on a divide-by-8 HFRC TPIU clock. + // If zero, other structure members are used to set the TPIU configuration. + // + uint32_t ui32SetItmBaud; + + // + //! MCU Control TRACECLKIN clock freq. + //! + //! Valid values for ui32TraceClkIn are: + //! + //! AM_HAL_TPIU_TRACECLKIN_6MHZ + //! AM_HAL_TPIU_TRACECLKIN_3MHZ + //! AM_HAL_TPIU_TRACECLKIN_1_5MHZ + //! AM_HAL_TPIU_TRACECLKIN_750KHZ + // + uint32_t ui32TraceClkIn; + + // + //! Protocol to use for the TPIU + //! + //! Valid values for ui32PinProtocol are: + //! + //! AM_HAL_TPIU_SPPR_PARALLEL + //! AM_HAL_TPIU_SPPR_MANCHESTER + //! AM_HAL_TPIU_SPPR_NRZ + // + uint32_t ui32PinProtocol; + + // + //! Desired width of the TPIU parallel port + // + uint32_t ui32ParallelPortSize; + + // + //! Desired Clock prescaler value + // + uint32_t ui32ClockPrescaler; +} +am_hal_tpiu_config_t; + +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern void am_hal_tpiu_clock_enable(void); +extern void am_hal_tpiu_clock_disable(void); +extern void am_hal_tpiu_port_width_set(uint32_t ui32PortWidth); +extern uint32_t am_hal_tpiu_supported_port_width_get(void); +extern uint32_t am_hal_tpiu_port_width_get(void); +extern void am_hal_tpiu_configure(am_hal_tpiu_config_t *psConfig); +extern void am_hal_tpiu_enable(am_hal_tpiu_config_t *psConfig); +extern void am_hal_tpiu_disable(void); + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_TPIU_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_ttp.c b/bsp/apollo2/libraries/drivers/hal/am_hal_ttp.c new file mode 100644 index 0000000000..77bde67b87 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_ttp.c @@ -0,0 +1,205 @@ +//***************************************************************************** +// +// am_hal_ttp.c +//! @file +//! +//! @brief Functions for handling the "two time program" interface. +//! +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#include "am_mcu_apollo.h" +#include "am_hal_ttp.h" + +//***************************************************************************** +// +// Local constants +// +//***************************************************************************** +#define TTP_ADDR 0x50020000 + +//***************************************************************************** +// +// Local prototypes +// +//***************************************************************************** +#if !defined(__GNUC__) +void __breakpoint(int val); +#endif + +//***************************************************************************** +// +// A function to verify that the TTP was saved and/or restored properly. +// +//***************************************************************************** +int +verifyTTPSaved(uint32_t *pSaveArray, int iNumWords) +{ + int ix, iErrCnt = 0; + uint32_t *pDataSpace = (uint32_t*)TTP_ADDR; + + for (ix = 0; ix +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +// Transmit and receive queue pointers for each UART module. +// +//***************************************************************************** +am_hal_queue_t g_psTxQueue[AM_REG_UART_NUM_MODULES]; +am_hal_queue_t g_psRxQueue[AM_REG_UART_NUM_MODULES]; + +//***************************************************************************** +// +// Power tracking structure +// +//***************************************************************************** +am_hal_uart_pwrsave_t am_hal_uart_pwrsave[AM_REG_UART_NUM_MODULES]; + +//***************************************************************************** +// +// Set Baud Rate based on the UART clock frequency. +// +//***************************************************************************** + +#define BAUDCLK (32) + +static void +config_baudrate(uint32_t ui32Module, uint32_t ui32Baudrate, uint32_t ui32UartClkFreq) +{ + uint64_t ui64FractionDivisorLong; + uint64_t ui64IntermediateLong; + uint32_t ui32IntegerDivisor; + uint32_t ui32FractionDivisor; + uint32_t ui32BaudClk; + + // + // Calculate register values. + // + ui32BaudClk = BAUDCLK * ui32Baudrate; + ui32IntegerDivisor = (uint32_t)(ui32UartClkFreq / ui32BaudClk); + ui64IntermediateLong = (ui32UartClkFreq * 64) / ui32BaudClk; + ui64FractionDivisorLong = ui64IntermediateLong - (ui32IntegerDivisor * 64); + ui32FractionDivisor = (uint32_t)ui64FractionDivisorLong; + + // + // Check the result. + // + am_hal_debug_assert_msg(ui32IntegerDivisor > 0, "Integer divisor MUST be greater than or equal to 1."); + + // + // Write the UART regs. + // + AM_REGn(UART, ui32Module, IBRD) = ui32IntegerDivisor; + AM_REGn(UART, ui32Module, IBRD) = ui32IntegerDivisor; + AM_REGn(UART, ui32Module, FBRD) = ui32FractionDivisor; +} + +//***************************************************************************** +// +//! @brief Set up the UART. +//! +//! @param psConfig pointer to a structure that holds the settings for the UART. +//! @param ui32UartclkFreq is clock frequency that the UART is running at. +//! +//! This function should be used to perform the initial set-up of the UART. +//! +//! @return none. +// +//***************************************************************************** +void +am_hal_uart_config(uint32_t ui32Module, am_hal_uart_config_t *psConfig) + +{ + uint32_t ui32ConfigVal = 0; + + // + // Configure the Baudrate. + // + config_baudrate(ui32Module, psConfig->ui32BaudRate, am_hal_clkgen_sysclk_get()); + + // + // OR in the Data bits. + // + ui32ConfigVal |= psConfig->ui32DataBits; + + // + // OR in the Two Stop bit if used. + // + ui32ConfigVal |= psConfig->bTwoStopBits ? AM_REG_UART_LCRH_STP2_M : 0; + + // + // OR in the Parity. + // + ui32ConfigVal |= psConfig->ui32Parity; + + // + // Write config to Line control register. + // + AM_REGn(UART, ui32Module, LCRH) |= ui32ConfigVal; + + // + // Write the flow control settings to the control register. + // + AM_REGn(UART, ui32Module, CR) |= psConfig->ui32FlowCtrl; + + // + // Set the clock select field for 24MHz from the HFRC + // + AM_REGn(UART, ui32Module, CR) |= AM_REG_UART_CR_CLKSEL_24MHZ; +} + +//***************************************************************************** +// +//! @brief Gets the status. +//! +//! This function returns the current status. +//! +//! @return current status. +// +//***************************************************************************** +uint32_t +am_hal_uart_status_get(uint32_t ui32Module) +{ + // + // Read and return the Status. + // + return AM_REGn(UART, ui32Module, RSR); +} + +//***************************************************************************** +// +//! @brief Gets the interrupt status. +//! +//! @param bEnabledOnly - If true returns the enabled interrupt status. +//! +//! This function returns the masked or raw interrupt status. +//! +//! @return Bitwise representation of the current interrupt status. +//! +//! The return value will be the logical OR of one or more of the following +//! values: +//! +//! AM_HAL_UART_INT_OVER_RUN +//! AM_HAL_UART_INT_BREAK_ERR +//! AM_HAL_UART_INT_PARITY_ERR +//! AM_HAL_UART_INT_FRAME_ERR +//! AM_HAL_UART_INT_RX_TMOUT +//! AM_HAL_UART_INT_TX +//! AM_REG_UART_IER_TXIM_M +//! AM_HAL_UART_INT_RX +//! AM_HAL_UART_INT_DSRM +//! AM_HAL_UART_INT_DCDM +//! AM_HAL_UART_INT_CTSM +//! AM_HAL_UART_INT_RIM +// +//***************************************************************************** +uint32_t +am_hal_uart_int_status_get(uint32_t ui32Module, bool bEnabledOnly) +{ + if (bEnabledOnly) + { + // + // Read and return the Masked Interrupt Status. + // + return AM_REGn(UART, ui32Module, MIS); + } + else + { + // + // Read and return the Raw Interrupt Status. + // + return AM_REGn(UART, ui32Module, IES); + } +} + +//***************************************************************************** +// +//! @brief Clears the desired interrupts. +//! +//! @param ui32Interrupt - Interrupt bits to clear. +//! +//! This function clears the desired interrupts. +//! +//! ui32Interrupt should be a logical or of the following: +//! +//! AM_HAL_UART_INT_OVER_RUN +//! AM_HAL_UART_INT_BREAK_ERR +//! AM_HAL_UART_INT_PARITY_ERR +//! AM_HAL_UART_INT_FRAME_ERR +//! AM_HAL_UART_INT_RX_TMOUT +//! AM_HAL_UART_INT_TX +//! AM_REG_UART_IER_TXIM_M +//! AM_HAL_UART_INT_RX +//! AM_HAL_UART_INT_DSRM +//! AM_HAL_UART_INT_DCDM +//! AM_HAL_UART_INT_CTSM +//! AM_HAL_UART_INT_RIM +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_int_clear(uint32_t ui32Module, uint32_t ui32Interrupt) +{ + // + // Clear the bits. + // + AM_REGn(UART, ui32Module, IEC) = ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Disables the desired interrupts. +//! +//! @param ui32Interrupt - Interrupt bits to disable. +//! +//! This function disables the desired interrupts. +//! +//! ui32Interrupt should be a logical or of the following: +//! +//! AM_HAL_UART_INT_OVER_RUN +//! AM_HAL_UART_INT_BREAK_ERR +//! AM_HAL_UART_INT_PARITY_ERR +//! AM_HAL_UART_INT_FRAME_ERR +//! AM_HAL_UART_INT_RX_TMOUT +//! AM_HAL_UART_INT_TX +//! AM_REG_UART_IER_TXIM_M +//! AM_HAL_UART_INT_RX +//! AM_HAL_UART_INT_DSRM +//! AM_HAL_UART_INT_DCDM +//! AM_HAL_UART_INT_CTSM +//! AM_HAL_UART_INT_RIM +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_int_disable(uint32_t ui32Module, uint32_t ui32Interrupt) +{ + // + // Disable the bits. + // + AM_REGn(UART, ui32Module, IER) &= ~ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Enables the desired interrupts. +//! +//! @param ui32Interrupt - Interrupt bits to enable. +//! +//! This function enables the desired interrupts. +//! +//! ui32Interrupt should be a logical or of the following: +//! +//! AM_HAL_UART_INT_OVER_RUN +//! AM_HAL_UART_INT_BREAK_ERR +//! AM_HAL_UART_INT_PARITY_ERR +//! AM_HAL_UART_INT_FRAME_ERR +//! AM_HAL_UART_INT_RX_TMOUT +//! AM_HAL_UART_INT_TX +//! AM_REG_UART_IER_TXIM_M +//! AM_HAL_UART_INT_RX +//! AM_HAL_UART_INT_DSRM +//! AM_HAL_UART_INT_DCDM +//! AM_HAL_UART_INT_CTSM +//! AM_HAL_UART_INT_RIM +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_int_enable(uint32_t ui32Module, uint32_t ui32Interrupt) +{ + // + // Enable the interrupts. + // + AM_REGn(UART, ui32Module, IER) |= ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Returns the enabled interrupts. +//! +//! This function return the enabled interrupts. +//! +//! @return the enabled interrupts. This will be a logical or of the following: +//! +//! AM_HAL_UART_INT_OVER_RUN +//! AM_HAL_UART_INT_BREAK_ERR +//! AM_HAL_UART_INT_PARITY_ERR +//! AM_HAL_UART_INT_FRAME_ERR +//! AM_HAL_UART_INT_RX_TMOUT +//! AM_HAL_UART_INT_TX +//! AM_REG_UART_IER_TXIM_M +//! AM_HAL_UART_INT_RX +//! AM_HAL_UART_INT_DSRM +//! AM_HAL_UART_INT_DCDM +//! AM_HAL_UART_INT_CTSM +//! AM_HAL_UART_INT_RIM +//! +//! @return Returns the enabled interrupts. +// +//***************************************************************************** +uint32_t +am_hal_uart_int_enable_get(uint32_t ui32Module) +{ + // + // Return the enabled interrupts. + // + return AM_REGn(UART, ui32Module, IER); +} + +//***************************************************************************** +// +//! @brief Enable the UART, RX, and TX. +//! +//! This function enables the UART, RX, and TX. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_enable(uint32_t ui32Module) +{ + // + // Enable the UART, RX, and TX. + // + AM_REGan_SET(UART, ui32Module, CR, (AM_REG_UART_CR_UARTEN_M | + AM_REG_UART_CR_RXE_M | + AM_REG_UART_CR_TXE_M) ); +} + +//***************************************************************************** +// +//! @brief Disable the UART, RX, and TX. +//! +//! This function disables the UART, RX, and TX. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_disable(uint32_t ui32Module) +{ + // + // Disable the UART. + // + AM_REGan_CLR(UART, ui32Module, CR, (AM_REG_UART_CR_UARTEN_M | + AM_REG_UART_CR_RXE_M | + AM_REG_UART_CR_TXE_M) ); +} + +//***************************************************************************** +// +//! @brief Enable the UART in the power control block. +//! +//! This function enables the UART device in the power control block. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_pwrctrl_enable(uint32_t ui32Module) +{ + // + // Check to make sure we're acting on a real UART module. + // + am_hal_debug_assert_msg(ui32Module < AM_REG_UART_NUM_MODULES, + "Trying to disable a UART module that doesn't exist"); + + am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_UART0 << ui32Module); +} + +//***************************************************************************** +// +//! @brief Disable the UART in the power control block. +//! +//! This function disables the UART device in the power control block. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_pwrctrl_disable(uint32_t ui32Module) +{ + // + // Check to make sure we're acting on a real UART module. + // + am_hal_debug_assert_msg(ui32Module < AM_REG_UART_NUM_MODULES, + "Trying to disable a UART module that doesn't exist"); + + am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_UART0 << ui32Module); +} + +//***************************************************************************** +// +//! @brief Enable the UART in the power control block. +//! +//! This function enables the UART device in the power control block. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_power_on_restore(uint32_t ui32Module) +{ + // + // Check to make sure we're acting on a real UART module. + // + am_hal_debug_assert_msg(ui32Module < AM_REG_UART_NUM_MODULES, + "Trying to enable a UART module that doesn't exist"); + + // + // Make sure this restore is a companion to a previous save call. + // + if ( am_hal_uart_pwrsave[ui32Module].bValid == 0 ) + { + return; + } + + // + // Enable power to the selected UART + // + am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_UART0 << ui32Module); + + // + // Restore the clock settings + // + am_hal_clkgen_uarten_set(ui32Module, am_hal_uart_pwrsave[ui32Module].UARTEN); + + // + // Restore the configuration registers from the global variable in SRAM. + // + AM_REGn(UART, ui32Module, ILPR) = am_hal_uart_pwrsave[ui32Module].ILPR; + AM_REGn(UART, ui32Module, IBRD) = am_hal_uart_pwrsave[ui32Module].IBRD; + AM_REGn(UART, ui32Module, FBRD) = am_hal_uart_pwrsave[ui32Module].FBRD; + AM_REGn(UART, ui32Module, LCRH) = am_hal_uart_pwrsave[ui32Module].LCRH; + AM_REGn(UART, ui32Module, CR) = am_hal_uart_pwrsave[ui32Module].CR; + AM_REGn(UART, ui32Module, IFLS) = am_hal_uart_pwrsave[ui32Module].IFLS; + AM_REGn(UART, ui32Module, IER) = am_hal_uart_pwrsave[ui32Module].IER; + + // + // Indicates we have restored the configuration. + // + am_hal_uart_pwrsave[ui32Module].bValid = 0; + + return; +} + +//***************************************************************************** +// +//! @brief Disable the UART in the power control block. +//! +//! This function disables the UART device in the power control block. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_power_off_save(uint32_t ui32Module) +{ + // + // Check to make sure we're acting on a real UART module. + // + am_hal_debug_assert_msg(ui32Module < AM_REG_UART_NUM_MODULES, + "Trying to disable a UART module that doesn't exist"); + + // + // Save all of the configuration register information for the selected + // UART. + // + am_hal_uart_pwrsave[ui32Module].ILPR = AM_REGn(UART, ui32Module, ILPR); + am_hal_uart_pwrsave[ui32Module].IBRD = AM_REGn(UART, ui32Module, IBRD); + am_hal_uart_pwrsave[ui32Module].FBRD = AM_REGn(UART, ui32Module, FBRD); + am_hal_uart_pwrsave[ui32Module].LCRH = AM_REGn(UART, ui32Module, LCRH); + am_hal_uart_pwrsave[ui32Module].CR = AM_REGn(UART, ui32Module, CR); + am_hal_uart_pwrsave[ui32Module].IFLS = AM_REGn(UART, ui32Module, IFLS); + am_hal_uart_pwrsave[ui32Module].IER = AM_REGn(UART, ui32Module, IER); + + // + // Save the clock setting and disable power to the selected UART. + // Save the current enable value. + // + am_hal_uart_pwrsave[ui32Module].UARTEN = + (AM_REG(CLKGEN, UARTEN) & AM_HAL_CLKGEN_UARTEN_UARTENn_M(ui32Module)) >> + AM_HAL_CLKGEN_UARTEN_UARTENn_S(ui32Module); + + // + // Disable the UART. + // + am_hal_clkgen_uarten_set(ui32Module, AM_HAL_CLKGEN_UARTEN_DIS); + + // + // Indicates we have a valid saved configuration. + // + am_hal_uart_pwrsave[ui32Module].bValid = 1; + + // + // Disable power to the selected UART. + // + am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_UART0 << ui32Module); + + return; +} + +//***************************************************************************** +// +//! @brief Enable the UART clock. +//! +//! This function enables the clock to the UART. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_clock_enable(uint32_t ui32Module) +{ + // + // Set CLKGEN.UARTEN, clear the field then write the desired enable value + // Valid enable values are DIS, EN, REDUCE_FREQ, EN_POWER_SAV. + // + am_hal_clkgen_uarten_set(ui32Module, AM_HAL_CLKGEN_UARTEN_EN); + + // + // Enable the UART clock. + // + AM_REGn(UART, ui32Module, CR) |= AM_REG_UART_CR_CLKEN_M; + + // + // Select default UART clock source + // + AM_REGn(UART, ui32Module, CR) |= AM_REG_UART_CR_CLKSEL_24MHZ; +} + +//***************************************************************************** +// +//! @brief Disable the UART clock. +//! +//! This function disables the clock to the UART. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_clock_disable(uint32_t ui32Module) +{ + // + // Disable the UART clock. + // + AM_REGn(UART, ui32Module, CR) &= ~AM_REG_UART_CR_CLKEN_M; + + // + // Disable the UART clock in the CLKGEN module. + // + am_hal_clkgen_uarten_set(ui32Module, AM_HAL_CLKGEN_UARTEN_DIS); +} + +//***************************************************************************** +// +//! @brief Set and enable the desired interrupt levels for the RX/TX fifo. +//! +//! @param ui32LvlCfg - Desired FIFO RX/TX levels. +//! +//! This function sets the desired interrupt levels for the RX/TX fifo and +//! enables the use of transmit and receive FIFO buffers. +//! +//! Valid values for ui32LvlCfg are: +//! +//! AM_HAL_UART_TX_FIFO_1_8 +//! AM_HAL_UART_TX_FIFO_1_4 +//! AM_HAL_UART_TX_FIFO_1_2 +//! AM_HAL_UART_TX_FIFO_3_4 +//! AM_HAL_UART_TX_FIFO_7_8 +//! +//! AM_HAL_UART_RX_FIFO_1_8 +//! AM_HAL_UART_RX_FIFO_1_4 +//! AM_HAL_UART_RX_FIFO_1_2 +//! AM_HAL_UART_RX_FIFO_3_4 +//! AM_HAL_UART_RX_FIFO_7_8 +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_fifo_config(uint32_t ui32Module, uint32_t ui32LvlCfg) +{ + // + // Enable the use of FIFOs. + // + AM_REGn(UART, ui32Module, LCRH) |= AM_REG_UART_LCRH_FEN_M; + + // + // Write the FIFO level register. + // + AM_REGn(UART, ui32Module, IFLS) = ui32LvlCfg; +} + +//***************************************************************************** +// +//! @brief Return the UART Flags. +//! +//! This function reads and returns the UART flags. +//! +//! @return Returns the Flags. +// +//***************************************************************************** +uint32_t +am_hal_uart_flags_get(uint32_t ui32Module) +{ + // + // Read and return the Flags. + // + return AM_REGn(UART, ui32Module, FR); +} + +//***************************************************************************** +// +//! @brief Outputs a single character using polling. +//! +//! @param cChar - Character to send. +//! +//! This function outputs a single character using polling. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_char_transmit_polled(uint32_t ui32Module, char cChar) +{ + // + // Wait for space, i.e. TX FIFO EMPTY + // + while (AM_BFRn(UART, ui32Module, FR, TXFF)); + + // + // Write the char. + // + AM_REGn(UART, ui32Module, DR) = cChar; +} + +//***************************************************************************** +// +//! @brief Outputs a zero terminated string using polling. +//! +//! @param pcString - Pointer to character string to send. +//! +//! This function outputs a zero terminated string using polling. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_string_transmit_polled(uint32_t ui32Module, char *pcString) +{ + while (*pcString) + { + // + // Wait for space, i.e. TX FIFO EMPTY. + // + while (AM_BFRn(UART, ui32Module, FR, TXFF)); + + // + // Write the char. + // + AM_REGn(UART, ui32Module, DR) = *pcString++; + } +} + +//***************************************************************************** +// +//! @brief Receives a character using polling. +//! +//! @param pcChar - Pointer to character to store received char. +//! +//! This function receives a character using polling. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_char_receive_polled(uint32_t ui32Module, char *pcChar) +{ + // + // Wait for data, i.e. RX FIFO NOT EMPTY. + // + while (AM_BFRn(UART, ui32Module, FR, RXFE)); + + // + // Save the char. + // + *pcChar = AM_REGn(UART, ui32Module, DR); +} + +//***************************************************************************** +// +//! @brief Receives one line using polling. +//! +//! @param ui32MaxChars - Maximum number of characters to receive. +//! @param pcChar - Pointer to character string to store received line. +//! +//! This function receives a line (delimited by '/n' or '/r') using polling. +//! Line buffer is 0 (NULL) terminated. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_line_receive_polled(uint32_t ui32Module, + uint32_t ui32MaxChars, + char *pcChar) +{ + char cRecChar; + uint32_t i; + + // + // Loop until we receive ui32MaxChars or receive a line ending. + // + for (i = 0; i < (ui32MaxChars - 1); i++) + { + // + // Get char. + // + am_hal_uart_char_receive_polled(ui32Module, &cRecChar); + + if ((cRecChar == '\n') || (cRecChar == '\r')) + { + // + // Zero terminate the buffer. + // + *pcChar = 0; + + return; + } + + *pcChar++ = cRecChar; + } +} + +//***************************************************************************** +// +//! @brief Initialize the buffered UART. +//! +//! @param pui8RxArray - Pointer to the RX buffer to fill. +//! @param ui32RxSize - size of RX buffer. +//! @param pui8TxArray - Pointer to the TX buffer to fill. +//! @param ui32TxSize - size of TX buffer. +//! +//! This function initializes the buffered UART. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_init_buffered(uint32_t ui32Module, + uint8_t *pui8RxArray, uint32_t ui32RxSize, + uint8_t *pui8TxArray, uint32_t ui32TxSize) +{ + // + // Enable the UART RX timeout interrupt. + // + AM_REGn(UART, ui32Module, IER) |= (AM_REG_UART_IES_RTRIS_M | + AM_REG_UART_IES_TXRIS_M); + + // + // Initialize the ring buffers. + // + am_hal_queue_init(&g_psTxQueue[ui32Module], pui8TxArray, 1, ui32TxSize); + am_hal_queue_init(&g_psRxQueue[ui32Module], pui8RxArray, 1, ui32RxSize); +} + +//***************************************************************************** +// +//! @brief Get the status of the buffered UART. +//! +//! @param pui32RxSize - Pointer to variable to return the Rx ring data size. +//! @param pui32TxSize - Pointer to variable to return the Tx ring data size. +//! +//! This function gets the status of the buffered UART. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_get_status_buffered(uint32_t ui32Module, + uint32_t *pui32RxSize, + uint32_t *pui32TxSize) +{ + // + // Return the current size of ring buffers. + // + if ( pui32RxSize ) + { + *pui32RxSize = am_hal_queue_data_left(&g_psRxQueue[ui32Module]); + } + + if ( pui32TxSize ) + { + *pui32TxSize = am_hal_queue_data_left(&g_psTxQueue[ui32Module]); + } +} + + +//***************************************************************************** +// +//! @brief Services the buffered UART. +//! +//! @param ui32Status is the contents of the UART interrupt status register. +//! +//! This function is responsible for servicing the buffered UART. Designed to +//! be called from the UART interrupt handler. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_uart_service_buffered(uint32_t ui32Module, uint32_t ui32Status) +{ + uint8_t ui8Character = '\x00'; + uint32_t ui32FifoEntry = 0; + + // + // Check to see if we have filled the Rx FIFO past the configured limit, or + // if we have an 'old' character or two sitting in the FIFO. + // + if (ui32Status & (AM_REG_UART_IES_RXRIS_M | AM_REG_UART_IES_RTRIS_M)) + { + // + // While there's stuff in the RX fifo.... + // + while (!AM_BFRn(UART, ui32Module, FR, RXFE)) + { + // + // Read each character out one by one, and add it to the ring + // buffer. This will start losing bytes if the fifo ever overflows. + // + ui32FifoEntry = AM_REGn(UART, ui32Module , DR); + + // + // As long as no error bits were set, we should push this byte to + // the FIFO. + // + if ( (ui32FifoEntry & 0xF00) == 0 ) + { + ui8Character = ui32FifoEntry & 0xFF; + am_hal_queue_item_add(&g_psRxQueue[ui32Module], &ui8Character, 1); + } + } + } + + // + // Check to see if our TX buffer has been recently emptied. If so, we + // should refill it from the TX ring buffer. + // + if (ui32Status & AM_REG_UART_IES_TXRIS_M) + { + // + // Keep refilling until the fifo is full, or the ring buffer is empty, + // whichever happens first. + // + while (am_hal_queue_data_left(&g_psTxQueue[ui32Module]) && + !AM_BFRn(UART, ui32Module, FR, TXFF)) + { + am_hal_queue_item_get(&g_psTxQueue[ui32Module], &ui8Character, 1); + AM_REGn(UART, ui32Module , DR) = ui8Character; + } + } +} + +//***************************************************************************** +// +//! @brief Services the buffered UART. +//! +//! @param ui32Status is the contents of the UART interrupt status register. +//! +//! This function is responsible for servicing the buffered UART. Designed to +//! be called from the UART interrupt handler. +//! +//! This function behaves exactly like am_hal_uart_service_buffered() \e except +//! it does not completely empty the RX FIFO on every interrupt event. Instead, +//! it will leave at least one byte behind until it receives a UART RX TIMEOUT +//! interrupt. If you use this service routine, you can treat the RX TIMEOUT +//! interrupt as a UART IDLE interrupt. Every time the UART RX line goes IDLE +//! for 32 consecutive bit-times you WILL receive a UART RX TIMEOUT interrupt. +//! This behavior is not guaranteed for am_hal_uart_service_buffered(). +//! +//! @return None +// +//***************************************************************************** +void +am_hal_uart_service_buffered_timeout_save(uint32_t ui32Module, uint32_t ui32Status) +{ + uint8_t ui8Character = '\x00'; + uint32_t ui32Count = 0; + uint32_t ui32FifoEntry = 0; + + // + // Check to see if we have filled the Rx FIFO past the configured limit, or + // if we have an 'old' character or two sitting in the FIFO. + // + if (ui32Status & (AM_REG_UART_IES_RXRIS_M | AM_REG_UART_IES_RTRIS_M)) + { + // + // Check to see what our FIFO configuration setting is. + // + uint32_t ui32FifoThreshold; + uint32_t ui32FifoCfg = AM_BFMn(UART, ui32Module, IFLS, RXIFLSEL); + + // + // Compute the number of bytes for receive interrupt from the FIFO level + // register. + // + switch(ui32FifoCfg) + { + case AM_HAL_UART_RX_FIFO_1_8: ui32FifoThreshold = 4; break; + case AM_HAL_UART_RX_FIFO_1_4: ui32FifoThreshold = 8; break; + case AM_HAL_UART_RX_FIFO_1_2: ui32FifoThreshold = 16; break; + case AM_HAL_UART_RX_FIFO_3_4: ui32FifoThreshold = 24; break; + case AM_HAL_UART_RX_FIFO_7_8: ui32FifoThreshold = 28; break; + default: + ui32FifoThreshold = 32; + } + + // + // While there's stuff in the RX fifo.... + // + while (!AM_BFRn(UART, ui32Module, FR, RXFE)) + { + // + // Read each character out one by one, and add it to the ring + // buffer. This will start losing bytes if the fifo ever overflows. + // + ui32FifoEntry = AM_REGn(UART, ui32Module, DR); + + // + // As long as no error bits were set, we should push this byte to + // the FIFO. + // + if ( (ui32FifoEntry & 0xF00) == 0) + { + ui8Character = ui32FifoEntry & 0xFF; + am_hal_queue_item_add(&g_psRxQueue[ui32Module], &ui8Character, 1); + } + + // + // Leave one byte to trigger the RX timeout interrupt. + // + if ( ++ui32Count >= (ui32FifoThreshold - 1) ) + { + break; + } + } + } + + // + // Check to see if our TX buffer has been recently emptied. If so, we + // should refill it from the TX ring buffer. + // + if (ui32Status & AM_REG_UART_IES_TXRIS_M) + { + // + // Keep refilling until the fifo is full, or the ring buffer is empty, + // whichever happens first. + // + while (am_hal_queue_data_left(&g_psTxQueue[ui32Module]) && + !AM_BFRn(UART, ui32Module, FR, TXFF)) + { + am_hal_queue_item_get(&g_psTxQueue[ui32Module], &ui8Character, 1); + AM_REGn(UART, ui32Module , DR) = ui8Character; + } + } +} + +//***************************************************************************** +// +//! @brief Puts a char in the buffer or directly to the fifo if available. +//! +//! @param cChar - Character to send. +//! +//! This function puts a character in the buffer or directly to the fifo. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_char_transmit_buffered(uint32_t ui32Module, char cChar) +{ + // + // Check the status of the Tx fifo and the Tx ring buffer. + // + if (am_hal_queue_empty(&g_psTxQueue[ui32Module]) && + !AM_BFRn(UART, ui32Module, FR, TXFF)) + { + // + // If the fifo isn't full yet, and the ring buffer isn't being used, + // just write the new character directly to the fifo. + // + AM_REGn(UART, ui32Module, DR) = cChar; + } + else + { + // + // If we get here, either the fifo is full, or the ring buffer is + // already in use. In either case, we need to use the ring buffer + // to make sure that the transmitted data gets sent in the right + // order. If the buffer is already full, we will simply lose this + // byte. + // + am_hal_queue_item_add(&g_psTxQueue[ui32Module], &cChar, 1); + } +} + +//***************************************************************************** +// +//! @brief Puts a null terminaled string in the buffer or directly to the fifo. +//! +//! @param pcString - Pointer to buffer used for sending. +//! +//! This function puts a string in the buffer or directly to the fifo if there +//! is space available. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_uart_string_transmit_buffered(uint32_t ui32Module, char *pcString) +{ + // + // Check the status of the Tx fifo and the Tx ring buffer. + // + while (*pcString) + { + if (am_hal_queue_empty(&g_psTxQueue[ui32Module]) && + !AM_BFRn(UART, ui32Module, FR, TXFF)) + { + // + // If the fifo isn't full yet, and the ring buffer isn't being used, + // just write the new character directly to the fifo. + // + AM_REGn(UART, ui32Module, DR) = *pcString; + } + else + { + // + // If we get here, either the fifo is full, or the ring buffer is + // already in use. In either case, we need to use the ring buffer + // to make sure that the transmitted data gets sent in the right + // order. If the buffer is already full, we will simply lose this + // byte. + // + am_hal_queue_item_add(&g_psTxQueue[ui32Module], pcString, 1); + } + + // + // Move the pointer to the next character. + // + pcString++; + } +} + +//***************************************************************************** +// +//! @brief Returns n number of characters from the ring buffer or until empty. +//! +//! @param pcString - Pointer to buffer for putting received characters. +//! @param ui32MaxChars - Maximum number of characters to receive. +//! +//! This function puts a char string in the buffer. +//! +//! @return Returns the number of chars received. +// +//***************************************************************************** +uint32_t +am_hal_uart_char_receive_buffered(uint32_t ui32Module, + char *pcString, + uint32_t ui32MaxChars) +{ + uint32_t ui32NumChars = 0; + + // + // Loop until ui32MaxChars or until empty. + // + while (am_hal_queue_data_left(&g_psRxQueue[ui32Module]) && ui32MaxChars) + { + // + // Pull a char out of the ring buffer. + // + am_hal_queue_item_get(&g_psRxQueue[ui32Module], pcString, 1); + + // + // Subtract from ui32MaxChars. + // Add to ui32NumChars. + // Move pointer in buffer. + // + ui32MaxChars--; + ui32NumChars++; + pcString++; + } + + // + // return the number of chars received. + // + return ui32NumChars; +} + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_uart.h b/bsp/apollo2/libraries/drivers/hal/am_hal_uart.h new file mode 100644 index 0000000000..4aab828582 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_uart.h @@ -0,0 +1,345 @@ +//***************************************************************************** +// +// am_hal_uart.h +//! @file +//! +//! @brief Functions for accessing and configuring the UART. +//! +//! @addtogroup uart2 UART +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_UART_H +#define AM_HAL_UART_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +//! @name UART Interrupts +//! @brief Macro definitions for UART FIFO levels. +//! +//! They may be used with the \e am_hal_uart_fifo_config() function. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_UART_INT_OVER_RUN AM_REG_UART_IER_OEIM_M +#define AM_HAL_UART_INT_BREAK_ERR AM_REG_UART_IER_BEIM_M +#define AM_HAL_UART_INT_PARITY_ERR AM_REG_UART_IER_PEIM_M +#define AM_HAL_UART_INT_FRAME_ERR AM_REG_UART_IER_FEIM_M +#define AM_HAL_UART_INT_RX_TMOUT AM_REG_UART_IER_RTIM_M +#define AM_HAL_UART_INT_TX AM_REG_UART_IER_TXIM_M +#define AM_HAL_UART_INT_RX AM_REG_UART_IER_RXIM_M +#define AM_HAL_UART_INT_DSRM AM_REG_UART_IER_DSRMIM_M +#define AM_HAL_UART_INT_DCDM AM_REG_UART_IER_DCDMIM_M +#define AM_HAL_UART_INT_CTSM AM_REG_UART_IER_CTSMIM_M +#define AM_HAL_UART_INT_TXCMP AM_REG_UART_IER_TXCMPMIM_M +//! @} + +//***************************************************************************** +// +//! @name UART FIFO Levels +//! @brief Macro definitions for RTV interrupt status bits. +//! +//! These macros correspond to the bits in the UART interrupt status register. +//! They may be used with any of the \e am_hal_uart_int_x() functions. +//! +//! @{ +// +//***************************************************************************** +//TX +#define AM_HAL_UART_TX_FIFO_1_8 AM_REG_UART_IFLS_TXIFLSEL(0) +#define AM_HAL_UART_TX_FIFO_1_4 AM_REG_UART_IFLS_TXIFLSEL(1) +#define AM_HAL_UART_TX_FIFO_1_2 AM_REG_UART_IFLS_TXIFLSEL(2) +#define AM_HAL_UART_TX_FIFO_3_4 AM_REG_UART_IFLS_TXIFLSEL(3) +#define AM_HAL_UART_TX_FIFO_7_8 AM_REG_UART_IFLS_TXIFLSEL(4) +// RX +#define AM_HAL_UART_RX_FIFO_1_8 AM_REG_UART_IFLS_RXIFLSEL(0) +#define AM_HAL_UART_RX_FIFO_1_4 AM_REG_UART_IFLS_RXIFLSEL(1) +#define AM_HAL_UART_RX_FIFO_1_2 AM_REG_UART_IFLS_RXIFLSEL(2) +#define AM_HAL_UART_RX_FIFO_3_4 AM_REG_UART_IFLS_RXIFLSEL(3) +#define AM_HAL_UART_RX_FIFO_7_8 AM_REG_UART_IFLS_RXIFLSEL(4) +//! @} + +//***************************************************************************** +// +//! @name UART Status Register +//! @brief Macro definitions for UART Status Register Bits. +//! +//! They may be used with the \e am_hal_uart_status_get() function. +//! +//! @{ +// +//***************************************************************************** +// This is the overrun error indicator. +#define AM_HAL_UART_RSR_OVERRUN_NOERR AM_REG_UART_RSR_OESTAT_NOERR +#define AM_HAL_UART_RSR_OVERRUN_ERROR AM_REG_UART_RSR_OESTAT_ERR + +// This is the break error indicator. +#define AM_HAL_UART_RSR_BREAK_NOERR AM_REG_UART_RSR_BESTAT_NOERR +#define AM_HAL_UART_RSR_BREAK_ERROR AM_REG_UART_RSR_BESTAT_ERR + +// This is the parity error indicator. +#define AM_HAL_UART_RSR_PARITY_NOERR AM_REG_UART_RSR_PESTAT_NOERR +#define AM_HAL_UART_RSR_PARITY_ERROR AM_REG_UART_RSR_PESTAT_ERR + +// This is the framing error indicator. +#define AM_HAL_UART_RSR_FRAME_ERROR_NOERR AM_REG_UART_RSR_FESTAT_NOERR +#define AM_HAL_UART_RSR_FRAME_ERROR_ERROR AM_REG_UART_RSR_FESTAT_ERR +//! @} + +//***************************************************************************** +// +//! @name UART Flag Register +//! @brief Macro definitions for UART Flag Register Bits. +//! +//! They may be used with the \e am_hal_uart_flags_get() function. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_UART_FR_RING AM_REG_UART_FR_RI_M +#define AM_HAL_UART_FR_TX_EMPTY AM_REG_UART_FR_TXFE_XMTFIFO_EMPTY +#define AM_HAL_UART_FR_RX_FULL AM_REG_UART_FR_RXFF_RCVFIFO_FULL +#define AM_HAL_UART_FR_TX_FULL AM_REG_UART_FR_TXFF_XMTFIFO_FULL +#define AM_HAL_UART_FR_RX_EMPTY AM_REG_UART_FR_RXFE_RCVFIFO_EMPTY +#define AM_HAL_UART_FR_BUSY AM_REG_UART_FR_BUSY_BUSY +#define AM_HAL_UART_FR_DCD_DETECTED AM_REG_UART_FR_DCD_DETECTED +#define AM_HAL_UART_FR_DSR_READY AM_REG_UART_FR_DSR_READY +#define AM_HAL_UART_FR_CTS AM_REG_UART_FR_CTS_M +//! @} + + +//***************************************************************************** +// +//! @name UART Config Macros +//! @brief Macro definitions for available Data bits. +//! +//! They may be used with the \e am_hal_uart_config_t structure used by \e +//! am_hal_uart_config(). +//! +//! @{ +// +//***************************************************************************** +//***************************************************************************** +// +// Data bits defines. +// +//***************************************************************************** +#define AM_HAL_UART_DATA_BITS_8 AM_REG_UART_LCRH_WLEN(3) +#define AM_HAL_UART_DATA_BITS_7 AM_REG_UART_LCRH_WLEN(2) +#define AM_HAL_UART_DATA_BITS_6 AM_REG_UART_LCRH_WLEN(1) +#define AM_HAL_UART_DATA_BITS_5 0 + +//***************************************************************************** +// +// Parity defines. +// +//***************************************************************************** +#define AM_HAL_UART_PARITY_NONE 0 +#define AM_HAL_UART_PARITY_ODD AM_REG_UART_LCRH_PEN_M +#define AM_HAL_UART_PARITY_EVEN AM_REG_UART_LCRH_PEN_M | \ + AM_REG_UART_LCRH_EPS_M + +//***************************************************************************** +// +// Flow control defines. +// +//***************************************************************************** +#define AM_HAL_UART_FLOW_CTRL_NONE 0 +#define AM_HAL_UART_FLOW_CTRL_RTS_CTS AM_REG_UART_CR_CTSEN_M | \ + AM_REG_UART_CR_RTSEN_M +//! @} + +//***************************************************************************** +// +//! UART configuration structure +// +//***************************************************************************** +typedef struct +{ + // + //! Desired Baudrate for the UART. + // + uint32_t ui32BaudRate; + + // + //! Number of data bits. + //! + //! Valid values for ui32DataBits are: + //! + //! AM_HAL_UART_DATA_BITS_8 + //! AM_HAL_UART_DATA_BITS_7 + //! AM_HAL_UART_DATA_BITS_6 + //! AM_HAL_UART_DATA_BITS_5 + // + uint32_t ui32DataBits; + + // + //! Use two stop bits. + // + bool bTwoStopBits; + + // + //! Parity. + //! + //! Valid values for ui32Parity are: + //! + //! AM_HAL_UART_PARITY_NONE + //! AM_HAL_UART_PARITY_ODD + //! AM_HAL_UART_PARITY_EVEN + // + uint32_t ui32Parity; + + // + //! Flow control. + //! + //! Valid values for ui32FlowCtrl are: + //! + //! AM_HAL_UART_FLOW_CTRL_NONE + //! AM_HAL_UART_FLOW_CTRL_RTS_CTS + // + uint32_t ui32FlowCtrl; +} +am_hal_uart_config_t; + +//***************************************************************************** +// +// Structure for containing information about the UART's configuration while +// it is powered down. +// +//***************************************************************************** +typedef struct +{ + uint32_t ILPR; + uint32_t IBRD; + uint32_t FBRD; + uint32_t LCRH; + uint32_t CR; + uint32_t IFLS; + uint32_t IER; + uint32_t UARTEN; + uint32_t bValid; +} +am_hal_uart_pwrsave_t; + +//***************************************************************************** +// +// Global Variables +// +//***************************************************************************** +extern am_hal_uart_pwrsave_t am_hal_uart_pwrsave[AM_REG_UART_NUM_MODULES]; + +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern void am_hal_uart_pwrctrl_enable(uint32_t ui32Module); +extern void am_hal_uart_pwrctrl_disable(uint32_t ui32Module); +extern void am_hal_uart_power_on_restore(uint32_t ui32Module); +extern void am_hal_uart_power_off_save(uint32_t ui32Module); +extern void am_hal_uart_config(uint32_t ui32Module, + am_hal_uart_config_t *psConfig); +extern uint32_t am_hal_uart_status_get(uint32_t ui32Module); +extern uint32_t am_hal_uart_int_status_get(uint32_t ui32Module, + bool bEnabledOnly); +extern void am_hal_uart_int_clear(uint32_t ui32Module, + uint32_t ui32Interrupt); +extern void am_hal_uart_int_disable(uint32_t ui32Module, + uint32_t ui32Interrupt); +extern void am_hal_uart_int_enable(uint32_t ui32Module, + uint32_t ui32Interrupt); +extern uint32_t am_hal_uart_int_enable_get(uint32_t ui32Module); +extern void am_hal_uart_enable(uint32_t ui32Module); +extern void am_hal_uart_disable(uint32_t ui32Module); +extern void am_hal_uart_clock_enable(uint32_t ui32Module); +extern void am_hal_uart_clock_disable(uint32_t ui32Module); +extern void am_hal_uart_fifo_config(uint32_t ui32Module, uint32_t ui32LvlCfg); +extern uint32_t am_hal_uart_flags_get(uint32_t ui32Module); + +// rx/tx polled +extern void am_hal_uart_char_transmit_polled(uint32_t ui32Module, + char cChar); +extern void am_hal_uart_string_transmit_polled(uint32_t ui32Module, + char *pcString); +extern void am_hal_uart_char_receive_polled(uint32_t ui32Module, + char *pcChar); +extern void am_hal_uart_line_receive_polled(uint32_t ui32Module, + uint32_t ui32MaxChars, + char *pcChar); + +// rx/tx buffered +extern void am_hal_uart_init_buffered(uint32_t ui32Module, + uint8_t *pui8RxArray, + uint32_t ui32RxSize, + uint8_t *pui8TxArray, + uint32_t ui32TxSize); +extern void am_hal_uart_get_status_buffered(uint32_t ui32Module, + uint32_t *pui32RxSize, + uint32_t *pui32TxSize); +extern void am_hal_uart_service_buffered(uint32_t ui32Module, + uint32_t ui32Status); + +extern void am_hal_uart_service_buffered_timeout_save(uint32_t ui32Module, + uint32_t ui32Status); +extern void am_hal_uart_char_transmit_buffered(uint32_t ui32Module, + char cChar); +extern void am_hal_uart_string_transmit_buffered(uint32_t ui32Module, + char *pcString); +extern uint32_t am_hal_uart_char_receive_buffered(uint32_t ui32Module, + char *pcString, + uint32_t ui32MaxChars); + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_UART_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_vcomp.c b/bsp/apollo2/libraries/drivers/hal/am_hal_vcomp.c new file mode 100644 index 0000000000..31e28855e4 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_vcomp.c @@ -0,0 +1,287 @@ +//***************************************************************************** +// +// am_hal_vcomp.c +//! @file +//! +//! @brief Functions for operating the on-chip Voltage Comparator +//! +//! @addtogroup vcomp2 Voltage Comparator (VCOMP) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +//! @brief Configure the Voltage Comparator module. +//! +//! @param psConfig is a structure containing configuration information for the +//! voltage comparator. +//! +//! This function configures the positive and negative input signals for the +//! voltage comparator. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_vcomp_config(const am_hal_vcomp_config_t *psConfig) +{ + // + // The configuration word should be a simple OR of the components of the + // configuration structure. + // + AM_REG(VCOMP, CFG) = (psConfig->ui32LevelSelect | + psConfig->ui32PosInput | + psConfig->ui32NegInput); +} + +//***************************************************************************** +// +//! @brief Set the Voltage Comparator DAC Level Select in Configuration Reg. +//! +//! @param ui32Level - DAC voltage selector (use macros enumerations) +//! +//! This function sets the DAC level select in the configuration register. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_vcomp_dac_level_set(uint32_t ui32Level) +{ + // + // Insert the supplied level into the vcomp configuration register + // + AM_BFW(VCOMP, CFG, LVLSEL, ui32Level >> AM_REG_VCOMP_CFG_LVLSEL_S); +} + +//***************************************************************************** +// +//! @brief Read the state of the voltage comparator. +//! +//! This function extracts the comparator state from the status register. +//! +//! @return the voltage comparator state +// +//***************************************************************************** +bool +am_hal_vcomp_read(void) +{ + return (AM_BFR(VCOMP, STAT, CMPOUT) == 1); +} + +//***************************************************************************** +// +//! @brief Enable the voltage comparator. +//! +//! This function powers up the voltage comparator. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_vcomp_enable(void) +{ + AM_REG(VCOMP, PWDKEY) = 0; +} + +//***************************************************************************** +// +//! @brief Disable the voltage comparator. +//! +//! This function powers down the voltage comparator. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_vcomp_disable(void) +{ + AM_REG(VCOMP, PWDKEY) = AM_REG_VCOMP_PWDKEY_KEYVAL; +} + +//***************************************************************************** +// +//! @brief Read the state of the voltage comparator interrupt status bits. +//! +//! @param bEnabledOnly - return the status of only the enabled interrupts. +//! +//! This function extracts the interrupt status bits and returns the raw or +//! only the enabled based on bEnabledOnly. +//! +//! @return Bitwise representation of the current interrupt status. +//! +//! The return value will be the logical OR of one or more of the following +//! values: +//! +//! AM_HAL_VCOMP_INT_OUTHI +//! AM_HAL_VCOMP_INT_OUTLO +// +//***************************************************************************** +uint32_t +am_hal_vcomp_int_status_get(bool bEnabledOnly) +{ + if (bEnabledOnly) + { + uint32_t u32RetVal = AM_REG(VCOMP, INTSTAT); + return u32RetVal & AM_REG(VCOMP, INTEN); + } + else + { + return AM_REG(VCOMP, INTSTAT); + } +} + +//***************************************************************************** +// +//! @brief Set the state of the voltage comparator interrupt status bits. +//! +//! @param ui32Interrupt - interrupts to be set. +//! +//! This function sets the specified interrupt status bits. +//! +//! ui32Interrupt should be a logical or of: +//! +//! AM_HAL_VCOMP_INT_OUTHI +//! AM_HAL_VCOMP_INT_OUTLO +//! +//! @return None +// +//***************************************************************************** +void +am_hal_vcomp_int_set(uint32_t ui32Interrupt) +{ + AM_REG(VCOMP, INTSET) = ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Clear the state of the voltage comparator interrupt status bits. +//! +//! @param ui32Interrupt - interrupts to be cleared. +//! +//! This function clears the specified interrupt status bits. +//! +//! ui32Interrupt should be a logical or of: +//! +//! AM_HAL_VCOMP_INT_OUTHI +//! AM_HAL_VCOMP_INT_OUTLO +//! +//! @return None +// +//***************************************************************************** +void +am_hal_vcomp_int_clear(uint32_t ui32Interrupt) +{ + AM_REG(VCOMP, INTCLR) = ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Enable the voltage comparator interrupt status bits. +//! +//! @param ui32Interrupt - interrupts to be enabled. +//! +//! This function enables desired interrupt status bits. +//! +//! ui32Interrupt should be a logical or of: +//! +//! AM_HAL_VCOMP_INT_OUTHI +//! AM_HAL_VCOMP_INT_OUTLO +//! +//! @return None +// +//***************************************************************************** +void +am_hal_vcomp_int_enable(uint32_t ui32Interrupt) +{ + AM_REG(VCOMP, INTEN) |= ui32Interrupt; +} + +//***************************************************************************** +// +//! @brief Return the enabled, voltage comparator interrupt status bits. +//! +//! This function returns the enabled interrupt status bits +//! +//! @return returns the enabled interrupt status bits. The return is a logical +//! or of: +//! +//! AM_HAL_VCOMP_INT_OUTHI +//! AM_HAL_VCOMP_INT_OUTLO +// +//***************************************************************************** +uint32_t +am_hal_vcomp_int_enable_get(void) +{ + return AM_REG(VCOMP, INTEN); +} + +//***************************************************************************** +// +//! @brief Disable the voltage comparator interrupt status bits. +//! +//! @param ui32Interrupt - interrupts to be disabled. +//! +//! This function disables desired interrupt status bits. +//! +//! ui32Interrupt should be a logical or of: +//! +//! AM_HAL_VCOMP_INT_OUTHI +//! AM_HAL_VCOMP_INT_OUTLO +//! +//! @return None +// +//***************************************************************************** +void +am_hal_vcomp_int_disable(uint32_t ui32Interrupt) +{ + AM_REG(VCOMP, INTEN) &= ~ui32Interrupt; +} + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_vcomp.h b/bsp/apollo2/libraries/drivers/hal/am_hal_vcomp.h new file mode 100644 index 0000000000..a6ca991aae --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_vcomp.h @@ -0,0 +1,176 @@ +//***************************************************************************** +// +// am_hal_vcomp.h +//! @file +//! +//! @brief Functions for operating the on-chip Voltage Comparator +//! +//! @addtogroup vcomp2 Voltage Comparator (VCOMP) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_VCOMP_H +#define AM_HAL_VCOMP_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +//! @name Positive Input Selection +//! @brief Use these macros to determine the positive input to the comparator. +//! @{ +// +//***************************************************************************** +#define AM_HAL_VCOMP_PSEL_VDDADJ AM_REG_VCOMP_CFG_PSEL_VDDADJ +#define AM_HAL_VCOMP_PSEL_VTEMP AM_REG_VCOMP_CFG_PSEL_VTEMP +#define AM_HAL_VCOMP_PSEL_VEXT1 AM_REG_VCOMP_CFG_PSEL_VEXT1 +#define AM_HAL_VCOMP_PSEL_VEXT2 AM_REG_VCOMP_CFG_PSEL_VEXT2 +//! @} + +//***************************************************************************** +// +//! @name Negative Input Selection +//! @brief Use these macros to determine the negative input to the comparator. +//! @{ +// +//***************************************************************************** +#define AM_HAL_VCOMP_NSEL_VREFEXT1 AM_REG_VCOMP_CFG_NSEL_VREFEXT1 +#define AM_HAL_VCOMP_NSEL_VREFEXT2 AM_REG_VCOMP_CFG_NSEL_VREFEXT2 +#define AM_HAL_VCOMP_NSEL_VREFEXT3 AM_REG_VCOMP_CFG_NSEL_VREFEXT3 +#define AM_HAL_VCOMP_NSEL_DAC_LEVEL AM_REG_VCOMP_CFG_NSEL_DAC +//! @} + +//***************************************************************************** +// +//! @name Negative Input DAC Selectioin +//! @brief Use these macros to determine the NSEL DAC voltage setting +//! @{ +// +//***************************************************************************** +#define AM_HAL_VCOMP_DAC_LVLSEL_0_58V AM_REG_VCOMP_CFG_LVLSEL_0P58V +#define AM_HAL_VCOMP_DAC_LVLSEL_0_77V AM_REG_VCOMP_CFG_LVLSEL_0P77V +#define AM_HAL_VCOMP_DAC_LVLSEL_0_97V AM_REG_VCOMP_CFG_LVLSEL_0P97V +#define AM_HAL_VCOMP_DAC_LVLSEL_1_16V AM_REG_VCOMP_CFG_LVLSEL_1P16V +#define AM_HAL_VCOMP_DAC_LVLSEL_1_35V AM_REG_VCOMP_CFG_LVLSEL_1P35V +#define AM_HAL_VCOMP_DAC_LVLSEL_1_55V AM_REG_VCOMP_CFG_LVLSEL_1P55V +#define AM_HAL_VCOMP_DAC_LVLSEL_1_74V AM_REG_VCOMP_CFG_LVLSEL_1P74V +#define AM_HAL_VCOMP_DAC_LVLSEL_1_93V AM_REG_VCOMP_CFG_LVLSEL_1P93V +#define AM_HAL_VCOMP_DAC_LVLSEL_2_13V AM_REG_VCOMP_CFG_LVLSEL_2P13V +#define AM_HAL_VCOMP_DAC_LVLSEL_2_32V AM_REG_VCOMP_CFG_LVLSEL_2P32V +#define AM_HAL_VCOMP_DAC_LVLSEL_2_51V AM_REG_VCOMP_CFG_LVLSEL_2P51V +#define AM_HAL_VCOMP_DAC_LVLSEL_2_71V AM_REG_VCOMP_CFG_LVLSEL_2P71V +#define AM_HAL_VCOMP_DAC_LVLSEL_2_90V AM_REG_VCOMP_CFG_LVLSEL_2P90V +#define AM_HAL_VCOMP_DAC_LVLSEL_3_09V AM_REG_VCOMP_CFG_LVLSEL_3P09V +#define AM_HAL_VCOMP_DAC_LVLSEL_3_29V AM_REG_VCOMP_CFG_LVLSEL_3P29V +#define AM_HAL_VCOMP_DAC_LVLSEL_3_48V AM_REG_VCOMP_CFG_LVLSEL_3P48V +//! @} + +//***************************************************************************** +// +//! @name Interrupt Status Bits +//! @brief Interrupt Status Bits for enable/disble use +//! +//! These macros may be used to set and clear interrupt bits +//! @{ +// +//***************************************************************************** +#define AM_HAL_VCOMP_INT_OUTHI AM_REG_VCOMP_INTEN_OUTHI_M +#define AM_HAL_VCOMP_INT_OUTLO AM_REG_VCOMP_INTEN_OUTLOW_M +//! @} + +//***************************************************************************** +// +//! @brief Configuration struct +// +//***************************************************************************** +typedef struct +{ + // + //! The DAC level setting + // + uint32_t ui32LevelSelect; + + // + //! The "positive" comparator input channel + //! + //! This channel is usually used as the signal to be monitored. + // + uint32_t ui32PosInput; + + // + //! The "negative" comparator input channel + //! + //! This channel is usually used as the reference signal. + // + uint32_t ui32NegInput; +} +am_hal_vcomp_config_t; + +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern void am_hal_vcomp_config(const am_hal_vcomp_config_t *psConfig); +extern void am_hal_vcomp_dac_level_set(uint32_t ui3Level); +extern bool am_hal_vcomp_read(void); +extern void am_hal_vcomp_enable(void); +extern void am_hal_vcomp_disable(void); +extern void am_hal_vcomp_int_enable(uint32_t ui32Interrupt); +extern uint32_t am_hal_vcomp_int_enable_get(void); +extern void am_hal_vcomp_int_disable(uint32_t ui32Interrupt); +extern void am_hal_vcomp_int_clear(uint32_t ui32Interrupt); +extern void am_hal_vcomp_int_set(uint32_t ui32Interrupt); +extern uint32_t am_hal_vcomp_int_status_get(bool bEnabledOnly); + +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_VCOMP_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_wdt.c b/bsp/apollo2/libraries/drivers/hal/am_hal_wdt.c new file mode 100644 index 0000000000..4e80113fd1 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_wdt.c @@ -0,0 +1,454 @@ +//***************************************************************************** +// +// am_hal_wdt.c +//! @file +//! +//! @brief Hardware abstraction layer for the Watchdog Timer module. +//! +//! @addtogroup wdt2 Watchdog Timer (WDT) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include +#include "am_mcu_apollo.h" + +//***************************************************************************** +// +// Adjacency check +// +// This is related to the timer read workaround. This macro checks to see if +// the two supplied count values are within one "tick" of eachother. It should +// still pass in the event of a timer rollover. The "B" read is assumed to +// follow the "A" read. The macro returns "TRUE" when the adjacent timer reads +// can be used. +// +//***************************************************************************** +#define adjacent(A, B) (((A) == (B)) || (((A) + 1) == (B)) || ((B) == 0)) + +//***************************************************************************** +// +//! @brief Configure the watchdog timer. +//! +//! @param psConfig - pointer to a configuration structure containing the +//! desired watchdog settings. +//! +//! This function will set the watchdog configuration register based on the +//! user's desired settings listed in the structure referenced by psConfig. If +//! the structure indicates that watchdog interrupts are desired, this function +//! will also set the interrupt enable bit in the configuration register. +//! +//! @note In order to actually receive watchdog interrupt and/or watchdog reset +//! events, the caller will also need to make sure that the watchdog interrupt +//! vector is enabled in the ARM NVIC, and that watchdog resets are enabled in +//! the reset generator module. Otherwise, the watchdog-generated interrupt and +//! reset events will have no effect. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_wdt_init(const am_hal_wdt_config_t *psConfig) +{ + uint32_t ui32ConfigVal; + uint16_t ui16IntCount, ui16ResetCount; + bool bResetEnabled = psConfig->ui32Config & AM_HAL_WDT_ENABLE_RESET; + bool bInterruptEnabled = psConfig->ui32Config & AM_HAL_WDT_ENABLE_INTERRUPT; + + // + // Read the desired settings from the psConfig structure. + // + ui16IntCount = psConfig->ui16InterruptCount; + ui16ResetCount = psConfig->ui16ResetCount; + + // + // Write the interrupt and reset count values to a temporary variable. + // + // Accept the passed Config value, but clear the Counts that we are about to set. + ui32ConfigVal = psConfig->ui32Config & ~(AM_REG_WDT_CFG_INTVAL_M | AM_REG_WDT_CFG_RESVAL_M); + ui32ConfigVal |= AM_WRITE_SM(AM_REG_WDT_CFG_INTVAL, ui16IntCount); + ui32ConfigVal |= AM_WRITE_SM(AM_REG_WDT_CFG_RESVAL, ui16ResetCount); + + // + // If interrupts should be enabled, set the appropriate bit in the + // temporary variable. Also, enable the interrupt in INTEN register in the + // watchdog module. + // + if ( bInterruptEnabled ) + { + // + // Enable the watchdog interrupt if the configuration calls for them. + // + AM_REGn(WDT, 0, INTEN) |= AM_REG_WDT_INTEN_WDT_M; + } + else + { + // + // Disable the watchdog interrupt if the configuration doesn't call for + // watchdog interrupts. + // + AM_REGn(WDT, 0, INTEN) &= ~AM_REG_WDT_INTEN_WDT_M; + } + + // + // If resets should be enabled, set the appropriate bit in the temporary + // variable. + // + if ( bResetEnabled ) + { + // + // Also enable watchdog resets in the reset module. + // + AM_REG(RSTGEN, CFG) |= AM_REG_RSTGEN_CFG_WDREN_M; + } + else + { + // + // Disable watchdog resets in the reset module. + // + AM_REG(RSTGEN, CFG) &= ~AM_REG_RSTGEN_CFG_WDREN_M; + } + + // + // Check for a user specified clock select. If none specified then + // set 128Hz. + // + if ( !(psConfig->ui32Config & AM_REG_WDT_CFG_CLKSEL_M) ) + { + ui32ConfigVal |= AM_REG_WDT_CFG_CLKSEL_128HZ; + } + + // + // Write the saved value to the watchdog configuration register. + // + AM_REGn(WDT, 0, CFG) = ui32ConfigVal; +} + +//***************************************************************************** +// +//! @brief Starts the watchdog timer. +//! +//! Enables the watchdog timer tick using the 'enable' bit in the watchdog +//! configuration register. This function does not perform any locking of the +//! watchdog timer, so it can be disabled or reconfigured later. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_wdt_start(void) +{ + // + // Make sure the watchdog timer is in the "reset" state, and then set the + // enable bit to start counting. + // + AM_REGn(WDT, 0, CFG) |= AM_REG_WDT_CFG_WDTEN_M; + AM_REGn(WDT, 0, RSTRT) |= AM_REG_WDT_RSTRT_RSTRT_KEYVALUE; + +} + +//***************************************************************************** +// +//! @brief Stops the watchdog timer. +//! +//! Disables the watchdog timer tick by clearing the 'enable' bit in the +//! watchdog configuration register. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_wdt_halt(void) +{ + + // + // Clear the watchdog enable bit. + // + AM_REGn(WDT, 0, CFG) &= ~AM_REG_WDT_CFG_WDTEN_M; +} + +//***************************************************************************** +// +//! @brief Locks the watchdog configuration and starts the watchdog timer. +//! +//! This function sets the watchdog "lock" register, which prevents software +//! from re-configuring the watchdog. This action will also set the enable bit +//! for the watchdog timer, so it will start counting immediately. +//! +//! @return None. +// +//***************************************************************************** +void +am_hal_wdt_lock_and_start(void) +{ + // + // Write the 'key' value to the watchdog lock register. + // + AM_REGn(WDT, 0, LOCK) = AM_REG_WDT_LOCK_LOCK_KEYVALUE; +} + +//***************************************************************************** +// +//! @brief Read the state of the wdt interrupt status. +//! +//! @param bEnabledOnly - return the status of only the enabled interrupts. +//! +//! This function extracts the interrupt status bits and returns the enabled or +//! raw based on bEnabledOnly. +//! +//! @return WDT interrupt status. +// +//***************************************************************************** +uint32_t +am_hal_wdt_int_status_get(bool bEnabledOnly) +{ + if (bEnabledOnly) + { + uint32_t u32RetVal = AM_REG(WDT, INTSTAT); + return u32RetVal & AM_REG(WDT, INTEN); + } + else + { + return AM_REG(WDT, INTSTAT); + } +} + +//***************************************************************************** +// +//! @brief Set the state of the wdt interrupt status bit. +//! +//! This function sets the interrupt bit. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_wdt_int_set(void) +{ + AM_REG(WDT, INTSET) = AM_REG_WDT_INTSET_WDT_M; +} + +//***************************************************************************** +// +//! @brief Clear the state of the wdt interrupt status bit. +//! +//! This function clear the interrupt bit. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_wdt_int_clear(void) +{ + AM_REGn(WDT, 0, INTCLR) = AM_REG_WDT_INTCLR_WDT_M; +} + +//***************************************************************************** +// +//! @brief Enable the wdt interrupt. +//! +//! This function enable the interrupt. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_wdt_int_enable(void) +{ + AM_REG(WDT, INTEN) |= AM_REG_WDT_INTSET_WDT_M; +} + +//***************************************************************************** +// +//! @brief Return the enabled WDT interrupts. +//! +//! This function returns the enabled WDT interrupts. +//! +//! @return enabled WDT interrupts. +// +//***************************************************************************** +uint32_t +am_hal_wdt_int_enable_get(void) +{ + return AM_REG(WDT, INTEN); +} + +//***************************************************************************** +// +//! @brief Disable the wdt interrupt. +//! +//! This function disablee the interrupt. +//! +//! @return None +// +//***************************************************************************** +void +am_hal_wdt_int_disable(void) +{ + AM_REG(WDT, INTEN) &= ~AM_REG_WDT_INTSET_WDT_M; +} + +//***************************************************************************** +// +// Static function for reading the WDT counter value. +// +//***************************************************************************** +#if defined(__GNUC_STDC_INLINE__) +__attribute__((naked)) +static +void +back2back_read_asm(uint32_t *pui32Array, uint32_t *pui32Register) +{ + // pui32Array[] is a pointer to a 3 word data array provided by the caller. + // pui32Register = address of the timer to be read. + __asm + ( + // Do 3 back-to-back reads of the register + " ldr r2, [r1, #0]\n" // Get counter register value + " ldr r3, [r1, #0]\n" // Get counter register value again + " ldr r1, [r1, #0]\n" // Get counter register value for a third time + " str r2, [r0, #0]\n" // Store register value to variable + " str r3, [r0, #4]\n" // Store register value to variable + " str r1, [r0, #8]\n" // Store register value to variable + " bx lr\n" + ); +} + +#elif defined(__ARMCC_VERSION) +__asm static uint32_t +back2back_read_asm(uint32_t *pui32Array, uint32_t *pui32Register) +{ + ldr r2, [r1, #0] // Get TMRn register value + ldr r3, [r1, #0] // Get TMRn register value again + ldr r1, [r1, #0] // Get TMRn register value for a third time + str r2, [r0, #0] // Store register value to variable + str r3, [r0, #4] // Store register value to variable + str r1, [r0, #8] // Store register value to variable + bx lr +} + +#elif defined(__IAR_SYSTEMS_ICC__) +#pragma diag_suppress = Pe940 // Suppress IAR compiler warning about missing + // return statement on a non-void function +__stackless static uint32_t +back2back_read_asm(uint32_t *pui32Array, uint32_t *pui32Register) +{ + __asm(" ldr r2, [r1, #0]"); // Get TMRn register value + __asm(" ldr r3, [r1, #0]"); // Get TMRn register value again + __asm(" ldr r1, [r1, #0]"); // Get TMRn register value for a third time + __asm(" str r2, [r0, #0]"); // Store register value to variable + __asm(" str r3, [r0, #4]"); // Store register value to variable + __asm(" str r1, [r0, #8]"); // Store register value to variable + __asm(" bx lr"); +} +#pragma diag_default = Pe940 // Restore IAR compiler warning +#endif + + +//***************************************************************************** +// +//! @brief Get the wdt counter value. +//! +//! This function reads the current value of watch dog timer counter register. +//! +//! WARNING caller is responsible for masking interrutps before calling this +//! function. +//! +//! @return None +// +//***************************************************************************** +uint32_t +am_hal_wdt_counter_get(void) +{ + uint32_t ui32Values[3] = {0}; + uint32_t ui32Value; + + // + // First, go read the value from the counter register 3 times + // back to back in assembly language. + // + back2back_read_asm(ui32Values, (uint32_t *)AM_REG_WDTn(0)); + + // + // Now, we'll figure out which of the three values is the correct time. + // + if (ui32Values[0] == ui32Values[1]) + { + // + // If the first two values match, then neither one was a bad read. + // We'll take this as the current time. + // + ui32Value = ui32Values[1]; + } + else + { + // + // If the first two values didn't match, then one of them might be bad. + // If one of the first two values is bad, then the third one should + // always be correct. We'll take the third value as the correct count. + // + ui32Value = ui32Values[2]; + + // + // If all of the statements about the architecture are true, the third + // value should be correct, and it should always be within one count of + // either the first or the second value. + // + // Just in case, we'll check against the previous two values to make + // sure that our final answer was reasonable. If it isn't, we will + // flag it as a "bad read", and fail this assert statement. + // + // This shouldn't ever happen, and it hasn't ever happened in any of + // our tests so far. + // + am_hal_debug_assert_msg((adjacent(ui32Values[1], ui32Values[2]) || + adjacent(ui32Values[0], ui32Values[2])), + "Bad CDT read"); + } + + return ui32Value; +} + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_wdt.h b/bsp/apollo2/libraries/drivers/hal/am_hal_wdt.h new file mode 100644 index 0000000000..63766fa458 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_wdt.h @@ -0,0 +1,184 @@ +//***************************************************************************** +// +// am_hal_wdt.h +//! @file +//! +//! @brief Hardware abstraction layer for the Watchdog Timer module. +//! +//! @addtogroup wdt2 Watchdog Timer (WDT) +//! @ingroup apollo2hal +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_HAL_WDT_H +#define AM_HAL_WDT_H + +#include +#include + +//***************************************************************************** +// +// Macro definitions +// +//***************************************************************************** + +//***************************************************************************** +// +//! @name WDT Clock Divider Selections. +//! @brief Macro definitions for WDT clock frequencies. +//! +//! These macros may be used with the am_hal_wdt_config_t structure to set the +//! clock frequency of the watch dog timer. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_WDT_LFRC_CLK_DEFAULT AM_REG_WDT_CFG_CLKSEL_128HZ +#define AM_HAL_WDT_LFRC_CLK_128HZ AM_REG_WDT_CFG_CLKSEL_128HZ +#define AM_HAL_WDT_LFRC_CLK_16HZ AM_REG_WDT_CFG_CLKSEL_16HZ +#define AM_HAL_WDT_LFRC_CLK_1HZ AM_REG_WDT_CFG_CLKSEL_1HZ +#define AM_HAL_WDT_LFRC_CLK_1_16HZ AM_REG_WDT_CFG_CLKSEL_1_16HZ +#define AM_HAL_WDT_LFRC_CLK_OFF AM_REG_WDT_CFG_CLKSEL_OFF +//! @} + +//***************************************************************************** +// +//! @name WDT Enable Reset in the WDT Configuration. +//! @brief Macro definitions for WDT Reset Enable. +//! +//! These macros may be used with the am_hal_wdt_config_t structure to enable +//! the watch dog timer to generate resets to the chip. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_WDT_ENABLE_RESET AM_REG_WDT_CFG_RESEN(1) +#define AM_HAL_WDT_DISABLE_RESET AM_REG_WDT_CFG_RESEN(0) +//! @} + +//***************************************************************************** +// +//! @name WDT Enable Interrupt Generation from the WDT Configuration. +//! @brief Macro definitions for WDT Interrupt Enable. +//! +//! These macros may be used with the am_hal_wdt_config_t structure to enable +//! the watch dog timer to generate generate WDT interrupts. +//! +//! @{ +// +//***************************************************************************** +#define AM_HAL_WDT_ENABLE_INTERRUPT AM_REG_WDT_CFG_INTEN(1) +#define AM_HAL_WDT_DISABLE_INTERRUPT AM_REG_WDT_CFG_INTEN(0) +//! @} + +//***************************************************************************** +// +//! @brief Watchdog timer configuration structure. +//! +//! This structure is made to be used with the am_hal_wdt_init() function. It +//! describes the configuration of the watchdog timer. +// +//***************************************************************************** +typedef struct +{ + //! Configuration Values for watchdog timer + //! event is generated. + uint32_t ui32Config; + + //! Number of watchdog timer ticks allowed before a watchdog interrupt + //! event is generated. + uint16_t ui16InterruptCount; + + //! Number of watchdog timer ticks allowed before the watchdog will issue a + //! system reset. + uint16_t ui16ResetCount; + +} +am_hal_wdt_config_t; + + +//***************************************************************************** +// +//! @brief Restarts the watchdog timer ("Pets" the dog) +//! +//! This function restarts the watchdog timer from the beginning, preventing +//! any interrupt or reset even from occuring until the next time the watchdog +//! timer expires. +//! +//! @return None. +// +//***************************************************************************** +#define am_hal_wdt_restart() \ + do \ + { \ + AM_REGn(WDT, 0, RSTRT) = AM_REG_WDT_RSTRT_RSTRT_KEYVALUE; \ + (void)AM_REGn(WDT, 0, RSTRT); \ + } \ + while(0) + +#ifdef __cplusplus +extern "C" +{ +#endif +//***************************************************************************** +// +// External function definitions +// +//***************************************************************************** +extern void am_hal_wdt_init(const am_hal_wdt_config_t *psConfig); +extern void am_hal_wdt_start(void); +extern void am_hal_wdt_halt(void); +extern void am_hal_wdt_lock_and_start(void); +extern void am_hal_wdt_int_enable(void); +extern uint32_t am_hal_wdt_int_enable_get(void); +extern void am_hal_wdt_int_disable(void); +extern void am_hal_wdt_int_clear(void); +extern void am_hal_wdt_int_set(void); +extern uint32_t am_hal_wdt_int_status_get(bool bEnabledOnly); +#ifdef __cplusplus +} +#endif + +#endif // AM_HAL_WDT_H + +//***************************************************************************** +// +// End Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_adc.h b/bsp/apollo2/libraries/drivers/regs/am_reg_adc.h new file mode 100644 index 0000000000..54d2d8620f --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_adc.h @@ -0,0 +1,864 @@ +//***************************************************************************** +// +// am_reg_adc.h +//! @file +//! +//! @brief Register macros for the ADC module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_ADC_H +#define AM_REG_ADC_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_ADC_NUM_MODULES 1 +#define AM_REG_ADCn(n) \ + (REG_ADC_BASEADDR + 0x00000000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_ADC_CFG_O 0x00000000 +#define AM_REG_ADC_STAT_O 0x00000004 +#define AM_REG_ADC_SWT_O 0x00000008 +#define AM_REG_ADC_SL0CFG_O 0x0000000C +#define AM_REG_ADC_SL1CFG_O 0x00000010 +#define AM_REG_ADC_SL2CFG_O 0x00000014 +#define AM_REG_ADC_SL3CFG_O 0x00000018 +#define AM_REG_ADC_SL4CFG_O 0x0000001C +#define AM_REG_ADC_SL5CFG_O 0x00000020 +#define AM_REG_ADC_SL6CFG_O 0x00000024 +#define AM_REG_ADC_SL7CFG_O 0x00000028 +#define AM_REG_ADC_WULIM_O 0x0000002C +#define AM_REG_ADC_WLLIM_O 0x00000030 +#define AM_REG_ADC_FIFO_O 0x00000038 +#define AM_REG_ADC_INTEN_O 0x00000200 +#define AM_REG_ADC_INTSTAT_O 0x00000204 +#define AM_REG_ADC_INTCLR_O 0x00000208 +#define AM_REG_ADC_INTSET_O 0x0000020C + +//***************************************************************************** +// +// ADC_INTEN - ADC Interrupt registers: Enable +// +//***************************************************************************** +// Window comparator voltage incursion interrupt. +#define AM_REG_ADC_INTEN_WCINC_S 5 +#define AM_REG_ADC_INTEN_WCINC_M 0x00000020 +#define AM_REG_ADC_INTEN_WCINC(n) (((uint32_t)(n) << 5) & 0x00000020) +#define AM_REG_ADC_INTEN_WCINC_WCINCINT 0x00000020 + +// Window comparator voltage excursion interrupt. +#define AM_REG_ADC_INTEN_WCEXC_S 4 +#define AM_REG_ADC_INTEN_WCEXC_M 0x00000010 +#define AM_REG_ADC_INTEN_WCEXC(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_ADC_INTEN_WCEXC_WCEXCINT 0x00000010 + +// FIFO 100 percent full interrupt. +#define AM_REG_ADC_INTEN_FIFOOVR2_S 3 +#define AM_REG_ADC_INTEN_FIFOOVR2_M 0x00000008 +#define AM_REG_ADC_INTEN_FIFOOVR2(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_ADC_INTEN_FIFOOVR2_FIFOFULLINT 0x00000008 + +// FIFO 75 percent full interrupt. +#define AM_REG_ADC_INTEN_FIFOOVR1_S 2 +#define AM_REG_ADC_INTEN_FIFOOVR1_M 0x00000004 +#define AM_REG_ADC_INTEN_FIFOOVR1(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_ADC_INTEN_FIFOOVR1_FIFO75INT 0x00000004 + +// ADC scan complete interrupt. +#define AM_REG_ADC_INTEN_SCNCMP_S 1 +#define AM_REG_ADC_INTEN_SCNCMP_M 0x00000002 +#define AM_REG_ADC_INTEN_SCNCMP(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_ADC_INTEN_SCNCMP_SCNCMPINT 0x00000002 + +// ADC conversion complete interrupt. +#define AM_REG_ADC_INTEN_CNVCMP_S 0 +#define AM_REG_ADC_INTEN_CNVCMP_M 0x00000001 +#define AM_REG_ADC_INTEN_CNVCMP(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_ADC_INTEN_CNVCMP_CNVCMPINT 0x00000001 + +//***************************************************************************** +// +// ADC_INTSTAT - ADC Interrupt registers: Status +// +//***************************************************************************** +// Window comparator voltage incursion interrupt. +#define AM_REG_ADC_INTSTAT_WCINC_S 5 +#define AM_REG_ADC_INTSTAT_WCINC_M 0x00000020 +#define AM_REG_ADC_INTSTAT_WCINC(n) (((uint32_t)(n) << 5) & 0x00000020) +#define AM_REG_ADC_INTSTAT_WCINC_WCINCINT 0x00000020 + +// Window comparator voltage excursion interrupt. +#define AM_REG_ADC_INTSTAT_WCEXC_S 4 +#define AM_REG_ADC_INTSTAT_WCEXC_M 0x00000010 +#define AM_REG_ADC_INTSTAT_WCEXC(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_ADC_INTSTAT_WCEXC_WCEXCINT 0x00000010 + +// FIFO 100 percent full interrupt. +#define AM_REG_ADC_INTSTAT_FIFOOVR2_S 3 +#define AM_REG_ADC_INTSTAT_FIFOOVR2_M 0x00000008 +#define AM_REG_ADC_INTSTAT_FIFOOVR2(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_ADC_INTSTAT_FIFOOVR2_FIFOFULLINT 0x00000008 + +// FIFO 75 percent full interrupt. +#define AM_REG_ADC_INTSTAT_FIFOOVR1_S 2 +#define AM_REG_ADC_INTSTAT_FIFOOVR1_M 0x00000004 +#define AM_REG_ADC_INTSTAT_FIFOOVR1(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_ADC_INTSTAT_FIFOOVR1_FIFO75INT 0x00000004 + +// ADC scan complete interrupt. +#define AM_REG_ADC_INTSTAT_SCNCMP_S 1 +#define AM_REG_ADC_INTSTAT_SCNCMP_M 0x00000002 +#define AM_REG_ADC_INTSTAT_SCNCMP(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_ADC_INTSTAT_SCNCMP_SCNCMPINT 0x00000002 + +// ADC conversion complete interrupt. +#define AM_REG_ADC_INTSTAT_CNVCMP_S 0 +#define AM_REG_ADC_INTSTAT_CNVCMP_M 0x00000001 +#define AM_REG_ADC_INTSTAT_CNVCMP(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_ADC_INTSTAT_CNVCMP_CNVCMPINT 0x00000001 + +//***************************************************************************** +// +// ADC_INTCLR - ADC Interrupt registers: Clear +// +//***************************************************************************** +// Window comparator voltage incursion interrupt. +#define AM_REG_ADC_INTCLR_WCINC_S 5 +#define AM_REG_ADC_INTCLR_WCINC_M 0x00000020 +#define AM_REG_ADC_INTCLR_WCINC(n) (((uint32_t)(n) << 5) & 0x00000020) +#define AM_REG_ADC_INTCLR_WCINC_WCINCINT 0x00000020 + +// Window comparator voltage excursion interrupt. +#define AM_REG_ADC_INTCLR_WCEXC_S 4 +#define AM_REG_ADC_INTCLR_WCEXC_M 0x00000010 +#define AM_REG_ADC_INTCLR_WCEXC(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_ADC_INTCLR_WCEXC_WCEXCINT 0x00000010 + +// FIFO 100 percent full interrupt. +#define AM_REG_ADC_INTCLR_FIFOOVR2_S 3 +#define AM_REG_ADC_INTCLR_FIFOOVR2_M 0x00000008 +#define AM_REG_ADC_INTCLR_FIFOOVR2(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_ADC_INTCLR_FIFOOVR2_FIFOFULLINT 0x00000008 + +// FIFO 75 percent full interrupt. +#define AM_REG_ADC_INTCLR_FIFOOVR1_S 2 +#define AM_REG_ADC_INTCLR_FIFOOVR1_M 0x00000004 +#define AM_REG_ADC_INTCLR_FIFOOVR1(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_ADC_INTCLR_FIFOOVR1_FIFO75INT 0x00000004 + +// ADC scan complete interrupt. +#define AM_REG_ADC_INTCLR_SCNCMP_S 1 +#define AM_REG_ADC_INTCLR_SCNCMP_M 0x00000002 +#define AM_REG_ADC_INTCLR_SCNCMP(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_ADC_INTCLR_SCNCMP_SCNCMPINT 0x00000002 + +// ADC conversion complete interrupt. +#define AM_REG_ADC_INTCLR_CNVCMP_S 0 +#define AM_REG_ADC_INTCLR_CNVCMP_M 0x00000001 +#define AM_REG_ADC_INTCLR_CNVCMP(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_ADC_INTCLR_CNVCMP_CNVCMPINT 0x00000001 + +//***************************************************************************** +// +// ADC_INTSET - ADC Interrupt registers: Set +// +//***************************************************************************** +// Window comparator voltage incursion interrupt. +#define AM_REG_ADC_INTSET_WCINC_S 5 +#define AM_REG_ADC_INTSET_WCINC_M 0x00000020 +#define AM_REG_ADC_INTSET_WCINC(n) (((uint32_t)(n) << 5) & 0x00000020) +#define AM_REG_ADC_INTSET_WCINC_WCINCINT 0x00000020 + +// Window comparator voltage excursion interrupt. +#define AM_REG_ADC_INTSET_WCEXC_S 4 +#define AM_REG_ADC_INTSET_WCEXC_M 0x00000010 +#define AM_REG_ADC_INTSET_WCEXC(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_ADC_INTSET_WCEXC_WCEXCINT 0x00000010 + +// FIFO 100 percent full interrupt. +#define AM_REG_ADC_INTSET_FIFOOVR2_S 3 +#define AM_REG_ADC_INTSET_FIFOOVR2_M 0x00000008 +#define AM_REG_ADC_INTSET_FIFOOVR2(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_ADC_INTSET_FIFOOVR2_FIFOFULLINT 0x00000008 + +// FIFO 75 percent full interrupt. +#define AM_REG_ADC_INTSET_FIFOOVR1_S 2 +#define AM_REG_ADC_INTSET_FIFOOVR1_M 0x00000004 +#define AM_REG_ADC_INTSET_FIFOOVR1(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_ADC_INTSET_FIFOOVR1_FIFO75INT 0x00000004 + +// ADC scan complete interrupt. +#define AM_REG_ADC_INTSET_SCNCMP_S 1 +#define AM_REG_ADC_INTSET_SCNCMP_M 0x00000002 +#define AM_REG_ADC_INTSET_SCNCMP(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_ADC_INTSET_SCNCMP_SCNCMPINT 0x00000002 + +// ADC conversion complete interrupt. +#define AM_REG_ADC_INTSET_CNVCMP_S 0 +#define AM_REG_ADC_INTSET_CNVCMP_M 0x00000001 +#define AM_REG_ADC_INTSET_CNVCMP(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_ADC_INTSET_CNVCMP_CNVCMPINT 0x00000001 + +//***************************************************************************** +// +// ADC_CFG - Configuration Register +// +//***************************************************************************** +// Select the source and frequency for the ADC clock. All values not enumerated +// below are undefined. +#define AM_REG_ADC_CFG_CLKSEL_S 24 +#define AM_REG_ADC_CFG_CLKSEL_M 0x03000000 +#define AM_REG_ADC_CFG_CLKSEL(n) (((uint32_t)(n) << 24) & 0x03000000) +#define AM_REG_ADC_CFG_CLKSEL_OFF 0x00000000 +#define AM_REG_ADC_CFG_CLKSEL_HFRC 0x01000000 +#define AM_REG_ADC_CFG_CLKSEL_HFRC_DIV2 0x02000000 + +// This bit selects the ADC trigger polarity for external off chip triggers. +#define AM_REG_ADC_CFG_TRIGPOL_S 19 +#define AM_REG_ADC_CFG_TRIGPOL_M 0x00080000 +#define AM_REG_ADC_CFG_TRIGPOL(n) (((uint32_t)(n) << 19) & 0x00080000) +#define AM_REG_ADC_CFG_TRIGPOL_RISING_EDGE 0x00000000 +#define AM_REG_ADC_CFG_TRIGPOL_FALLING_EDGE 0x00080000 + +// Select the ADC trigger source. +#define AM_REG_ADC_CFG_TRIGSEL_S 16 +#define AM_REG_ADC_CFG_TRIGSEL_M 0x00070000 +#define AM_REG_ADC_CFG_TRIGSEL(n) (((uint32_t)(n) << 16) & 0x00070000) +#define AM_REG_ADC_CFG_TRIGSEL_EXT0 0x00000000 +#define AM_REG_ADC_CFG_TRIGSEL_EXT1 0x00010000 +#define AM_REG_ADC_CFG_TRIGSEL_EXT2 0x00020000 +#define AM_REG_ADC_CFG_TRIGSEL_EXT3 0x00030000 +#define AM_REG_ADC_CFG_TRIGSEL_VCOMP 0x00040000 +#define AM_REG_ADC_CFG_TRIGSEL_SWT 0x00070000 + +// Select the ADC reference voltage. +#define AM_REG_ADC_CFG_REFSEL_S 8 +#define AM_REG_ADC_CFG_REFSEL_M 0x00000300 +#define AM_REG_ADC_CFG_REFSEL(n) (((uint32_t)(n) << 8) & 0x00000300) +#define AM_REG_ADC_CFG_REFSEL_INT2P0 0x00000000 +#define AM_REG_ADC_CFG_REFSEL_INT1P5 0x00000100 +#define AM_REG_ADC_CFG_REFSEL_EXT2P0 0x00000200 +#define AM_REG_ADC_CFG_REFSEL_EXT1P5 0x00000300 + +// Clock mode register +#define AM_REG_ADC_CFG_CKMODE_S 4 +#define AM_REG_ADC_CFG_CKMODE_M 0x00000010 +#define AM_REG_ADC_CFG_CKMODE(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_ADC_CFG_CKMODE_LPCKMODE 0x00000000 +#define AM_REG_ADC_CFG_CKMODE_LLCKMODE 0x00000010 + +// Select power mode to enter between active scans. +#define AM_REG_ADC_CFG_LPMODE_S 3 +#define AM_REG_ADC_CFG_LPMODE_M 0x00000008 +#define AM_REG_ADC_CFG_LPMODE(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_ADC_CFG_LPMODE_MODE0 0x00000000 +#define AM_REG_ADC_CFG_LPMODE_MODE1 0x00000008 + +// This bit enables Repeating Scan Mode. +#define AM_REG_ADC_CFG_RPTEN_S 2 +#define AM_REG_ADC_CFG_RPTEN_M 0x00000004 +#define AM_REG_ADC_CFG_RPTEN(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_ADC_CFG_RPTEN_SINGLE_SCAN 0x00000000 +#define AM_REG_ADC_CFG_RPTEN_REPEATING_SCAN 0x00000004 + +// This bit enables the ADC module. While the ADC is enabled, the ADCCFG and +// SLOT Configuration regsiter settings must remain stable and unchanged. All +// configuration register settings, slot configuration settings and window +// comparison settings should be written prior to setting the ADCEN bit to '1'. +#define AM_REG_ADC_CFG_ADCEN_S 0 +#define AM_REG_ADC_CFG_ADCEN_M 0x00000001 +#define AM_REG_ADC_CFG_ADCEN(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_ADC_CFG_ADCEN_DIS 0x00000000 +#define AM_REG_ADC_CFG_ADCEN_EN 0x00000001 + +//***************************************************************************** +// +// ADC_STAT - ADC Power Status +// +//***************************************************************************** +// Indicates the power-status of the ADC. +#define AM_REG_ADC_STAT_PWDSTAT_S 0 +#define AM_REG_ADC_STAT_PWDSTAT_M 0x00000001 +#define AM_REG_ADC_STAT_PWDSTAT(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_ADC_STAT_PWDSTAT_ON 0x00000000 +#define AM_REG_ADC_STAT_PWDSTAT_POWERED_DOWN 0x00000001 + +//***************************************************************************** +// +// ADC_SWT - Software trigger +// +//***************************************************************************** +// Writing 0x37 to this register generates a software trigger. +#define AM_REG_ADC_SWT_SWT_S 0 +#define AM_REG_ADC_SWT_SWT_M 0x000000FF +#define AM_REG_ADC_SWT_SWT(n) (((uint32_t)(n) << 0) & 0x000000FF) +#define AM_REG_ADC_SWT_SWT_GEN_SW_TRIGGER 0x00000037 + +//***************************************************************************** +// +// ADC_SL0CFG - Slot 0 Configuration Register +// +//***************************************************************************** +// Select the number of measurements to average in the accumulate divide module +// for this slot. +#define AM_REG_ADC_SL0CFG_ADSEL0_S 24 +#define AM_REG_ADC_SL0CFG_ADSEL0_M 0x07000000 +#define AM_REG_ADC_SL0CFG_ADSEL0(n) (((uint32_t)(n) << 24) & 0x07000000) +#define AM_REG_ADC_SL0CFG_ADSEL0_AVG_1_MSRMT 0x00000000 +#define AM_REG_ADC_SL0CFG_ADSEL0_AVG_2_MSRMTS 0x01000000 +#define AM_REG_ADC_SL0CFG_ADSEL0_AVG_4_MSRMTS 0x02000000 +#define AM_REG_ADC_SL0CFG_ADSEL0_AVG_8_MSRMT 0x03000000 +#define AM_REG_ADC_SL0CFG_ADSEL0_AVG_16_MSRMTS 0x04000000 +#define AM_REG_ADC_SL0CFG_ADSEL0_AVG_32_MSRMTS 0x05000000 +#define AM_REG_ADC_SL0CFG_ADSEL0_AVG_64_MSRMTS 0x06000000 +#define AM_REG_ADC_SL0CFG_ADSEL0_AVG_128_MSRMTS 0x07000000 + +// Set the Precision Mode For Slot. +#define AM_REG_ADC_SL0CFG_PRMODE0_S 16 +#define AM_REG_ADC_SL0CFG_PRMODE0_M 0x00030000 +#define AM_REG_ADC_SL0CFG_PRMODE0(n) (((uint32_t)(n) << 16) & 0x00030000) +#define AM_REG_ADC_SL0CFG_PRMODE0_P14B 0x00000000 +#define AM_REG_ADC_SL0CFG_PRMODE0_P12B 0x00010000 +#define AM_REG_ADC_SL0CFG_PRMODE0_P10B 0x00020000 +#define AM_REG_ADC_SL0CFG_PRMODE0_P8B 0x00030000 + +// Select one of the 14 channel inputs for this slot. +#define AM_REG_ADC_SL0CFG_CHSEL0_S 8 +#define AM_REG_ADC_SL0CFG_CHSEL0_M 0x00000F00 +#define AM_REG_ADC_SL0CFG_CHSEL0(n) (((uint32_t)(n) << 8) & 0x00000F00) +#define AM_REG_ADC_SL0CFG_CHSEL0_SE0 0x00000000 +#define AM_REG_ADC_SL0CFG_CHSEL0_SE1 0x00000100 +#define AM_REG_ADC_SL0CFG_CHSEL0_SE2 0x00000200 +#define AM_REG_ADC_SL0CFG_CHSEL0_SE3 0x00000300 +#define AM_REG_ADC_SL0CFG_CHSEL0_SE4 0x00000400 +#define AM_REG_ADC_SL0CFG_CHSEL0_SE5 0x00000500 +#define AM_REG_ADC_SL0CFG_CHSEL0_SE6 0x00000600 +#define AM_REG_ADC_SL0CFG_CHSEL0_SE7 0x00000700 +#define AM_REG_ADC_SL0CFG_CHSEL0_SE8 0x00000800 +#define AM_REG_ADC_SL0CFG_CHSEL0_SE9 0x00000900 +#define AM_REG_ADC_SL0CFG_CHSEL0_DF0 0x00000A00 +#define AM_REG_ADC_SL0CFG_CHSEL0_DF1 0x00000B00 +#define AM_REG_ADC_SL0CFG_CHSEL0_TEMP 0x00000C00 +#define AM_REG_ADC_SL0CFG_CHSEL0_BATT 0x00000D00 +#define AM_REG_ADC_SL0CFG_CHSEL0_VSS 0x00000E00 + +// This bit enables the window compare function for slot 0. +#define AM_REG_ADC_SL0CFG_WCEN0_S 1 +#define AM_REG_ADC_SL0CFG_WCEN0_M 0x00000002 +#define AM_REG_ADC_SL0CFG_WCEN0(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_ADC_SL0CFG_WCEN0_WCEN 0x00000002 + +// This bit enables slot 0 for ADC conversions. +#define AM_REG_ADC_SL0CFG_SLEN0_S 0 +#define AM_REG_ADC_SL0CFG_SLEN0_M 0x00000001 +#define AM_REG_ADC_SL0CFG_SLEN0(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_ADC_SL0CFG_SLEN0_SLEN 0x00000001 + +//***************************************************************************** +// +// ADC_SL1CFG - Slot 1 Configuration Register +// +//***************************************************************************** +// Select the number of measurements to average in the accumulate divide module +// for this slot. +#define AM_REG_ADC_SL1CFG_ADSEL1_S 24 +#define AM_REG_ADC_SL1CFG_ADSEL1_M 0x07000000 +#define AM_REG_ADC_SL1CFG_ADSEL1(n) (((uint32_t)(n) << 24) & 0x07000000) +#define AM_REG_ADC_SL1CFG_ADSEL1_AVG_1_MSRMT 0x00000000 +#define AM_REG_ADC_SL1CFG_ADSEL1_AVG_2_MSRMTS 0x01000000 +#define AM_REG_ADC_SL1CFG_ADSEL1_AVG_4_MSRMTS 0x02000000 +#define AM_REG_ADC_SL1CFG_ADSEL1_AVG_8_MSRMT 0x03000000 +#define AM_REG_ADC_SL1CFG_ADSEL1_AVG_16_MSRMTS 0x04000000 +#define AM_REG_ADC_SL1CFG_ADSEL1_AVG_32_MSRMTS 0x05000000 +#define AM_REG_ADC_SL1CFG_ADSEL1_AVG_64_MSRMTS 0x06000000 +#define AM_REG_ADC_SL1CFG_ADSEL1_AVG_128_MSRMTS 0x07000000 + +// Set the Precision Mode For Slot. +#define AM_REG_ADC_SL1CFG_PRMODE1_S 16 +#define AM_REG_ADC_SL1CFG_PRMODE1_M 0x00030000 +#define AM_REG_ADC_SL1CFG_PRMODE1(n) (((uint32_t)(n) << 16) & 0x00030000) +#define AM_REG_ADC_SL1CFG_PRMODE1_P14B 0x00000000 +#define AM_REG_ADC_SL1CFG_PRMODE1_P12B 0x00010000 +#define AM_REG_ADC_SL1CFG_PRMODE1_P10B 0x00020000 +#define AM_REG_ADC_SL1CFG_PRMODE1_P8B 0x00030000 + +// Select one of the 14 channel inputs for this slot. +#define AM_REG_ADC_SL1CFG_CHSEL1_S 8 +#define AM_REG_ADC_SL1CFG_CHSEL1_M 0x00000F00 +#define AM_REG_ADC_SL1CFG_CHSEL1(n) (((uint32_t)(n) << 8) & 0x00000F00) +#define AM_REG_ADC_SL1CFG_CHSEL1_SE0 0x00000000 +#define AM_REG_ADC_SL1CFG_CHSEL1_SE1 0x00000100 +#define AM_REG_ADC_SL1CFG_CHSEL1_SE2 0x00000200 +#define AM_REG_ADC_SL1CFG_CHSEL1_SE3 0x00000300 +#define AM_REG_ADC_SL1CFG_CHSEL1_SE4 0x00000400 +#define AM_REG_ADC_SL1CFG_CHSEL1_SE5 0x00000500 +#define AM_REG_ADC_SL1CFG_CHSEL1_SE6 0x00000600 +#define AM_REG_ADC_SL1CFG_CHSEL1_SE7 0x00000700 +#define AM_REG_ADC_SL1CFG_CHSEL1_SE8 0x00000800 +#define AM_REG_ADC_SL1CFG_CHSEL1_SE9 0x00000900 +#define AM_REG_ADC_SL1CFG_CHSEL1_DF0 0x00000A00 +#define AM_REG_ADC_SL1CFG_CHSEL1_DF1 0x00000B00 +#define AM_REG_ADC_SL1CFG_CHSEL1_TEMP 0x00000C00 +#define AM_REG_ADC_SL1CFG_CHSEL1_BATT 0x00000D00 +#define AM_REG_ADC_SL1CFG_CHSEL1_VSS 0x00000E00 + +// This bit enables the window compare function for slot 1. +#define AM_REG_ADC_SL1CFG_WCEN1_S 1 +#define AM_REG_ADC_SL1CFG_WCEN1_M 0x00000002 +#define AM_REG_ADC_SL1CFG_WCEN1(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_ADC_SL1CFG_WCEN1_WCEN 0x00000002 + +// This bit enables slot 1 for ADC conversions. +#define AM_REG_ADC_SL1CFG_SLEN1_S 0 +#define AM_REG_ADC_SL1CFG_SLEN1_M 0x00000001 +#define AM_REG_ADC_SL1CFG_SLEN1(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_ADC_SL1CFG_SLEN1_SLEN 0x00000001 + +//***************************************************************************** +// +// ADC_SL2CFG - Slot 2 Configuration Register +// +//***************************************************************************** +// Select the number of measurements to average in the accumulate divide module +// for this slot. +#define AM_REG_ADC_SL2CFG_ADSEL2_S 24 +#define AM_REG_ADC_SL2CFG_ADSEL2_M 0x07000000 +#define AM_REG_ADC_SL2CFG_ADSEL2(n) (((uint32_t)(n) << 24) & 0x07000000) +#define AM_REG_ADC_SL2CFG_ADSEL2_AVG_1_MSRMT 0x00000000 +#define AM_REG_ADC_SL2CFG_ADSEL2_AVG_2_MSRMTS 0x01000000 +#define AM_REG_ADC_SL2CFG_ADSEL2_AVG_4_MSRMTS 0x02000000 +#define AM_REG_ADC_SL2CFG_ADSEL2_AVG_8_MSRMT 0x03000000 +#define AM_REG_ADC_SL2CFG_ADSEL2_AVG_16_MSRMTS 0x04000000 +#define AM_REG_ADC_SL2CFG_ADSEL2_AVG_32_MSRMTS 0x05000000 +#define AM_REG_ADC_SL2CFG_ADSEL2_AVG_64_MSRMTS 0x06000000 +#define AM_REG_ADC_SL2CFG_ADSEL2_AVG_128_MSRMTS 0x07000000 + +// Set the Precision Mode For Slot. +#define AM_REG_ADC_SL2CFG_PRMODE2_S 16 +#define AM_REG_ADC_SL2CFG_PRMODE2_M 0x00030000 +#define AM_REG_ADC_SL2CFG_PRMODE2(n) (((uint32_t)(n) << 16) & 0x00030000) +#define AM_REG_ADC_SL2CFG_PRMODE2_P14B 0x00000000 +#define AM_REG_ADC_SL2CFG_PRMODE2_P12B 0x00010000 +#define AM_REG_ADC_SL2CFG_PRMODE2_P10B 0x00020000 +#define AM_REG_ADC_SL2CFG_PRMODE2_P8B 0x00030000 + +// Select one of the 14 channel inputs for this slot. +#define AM_REG_ADC_SL2CFG_CHSEL2_S 8 +#define AM_REG_ADC_SL2CFG_CHSEL2_M 0x00000F00 +#define AM_REG_ADC_SL2CFG_CHSEL2(n) (((uint32_t)(n) << 8) & 0x00000F00) +#define AM_REG_ADC_SL2CFG_CHSEL2_SE0 0x00000000 +#define AM_REG_ADC_SL2CFG_CHSEL2_SE1 0x00000100 +#define AM_REG_ADC_SL2CFG_CHSEL2_SE2 0x00000200 +#define AM_REG_ADC_SL2CFG_CHSEL2_SE3 0x00000300 +#define AM_REG_ADC_SL2CFG_CHSEL2_SE4 0x00000400 +#define AM_REG_ADC_SL2CFG_CHSEL2_SE5 0x00000500 +#define AM_REG_ADC_SL2CFG_CHSEL2_SE6 0x00000600 +#define AM_REG_ADC_SL2CFG_CHSEL2_SE7 0x00000700 +#define AM_REG_ADC_SL2CFG_CHSEL2_SE8 0x00000800 +#define AM_REG_ADC_SL2CFG_CHSEL2_SE9 0x00000900 +#define AM_REG_ADC_SL2CFG_CHSEL2_DF0 0x00000A00 +#define AM_REG_ADC_SL2CFG_CHSEL2_DF1 0x00000B00 +#define AM_REG_ADC_SL2CFG_CHSEL2_TEMP 0x00000C00 +#define AM_REG_ADC_SL2CFG_CHSEL2_BATT 0x00000D00 +#define AM_REG_ADC_SL2CFG_CHSEL2_VSS 0x00000E00 + +// This bit enables the window compare function for slot 2. +#define AM_REG_ADC_SL2CFG_WCEN2_S 1 +#define AM_REG_ADC_SL2CFG_WCEN2_M 0x00000002 +#define AM_REG_ADC_SL2CFG_WCEN2(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_ADC_SL2CFG_WCEN2_WCEN 0x00000002 + +// This bit enables slot 2 for ADC conversions. +#define AM_REG_ADC_SL2CFG_SLEN2_S 0 +#define AM_REG_ADC_SL2CFG_SLEN2_M 0x00000001 +#define AM_REG_ADC_SL2CFG_SLEN2(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_ADC_SL2CFG_SLEN2_SLEN 0x00000001 + +//***************************************************************************** +// +// ADC_SL3CFG - Slot 3 Configuration Register +// +//***************************************************************************** +// Select the number of measurements to average in the accumulate divide module +// for this slot. +#define AM_REG_ADC_SL3CFG_ADSEL3_S 24 +#define AM_REG_ADC_SL3CFG_ADSEL3_M 0x07000000 +#define AM_REG_ADC_SL3CFG_ADSEL3(n) (((uint32_t)(n) << 24) & 0x07000000) +#define AM_REG_ADC_SL3CFG_ADSEL3_AVG_1_MSRMT 0x00000000 +#define AM_REG_ADC_SL3CFG_ADSEL3_AVG_2_MSRMTS 0x01000000 +#define AM_REG_ADC_SL3CFG_ADSEL3_AVG_4_MSRMTS 0x02000000 +#define AM_REG_ADC_SL3CFG_ADSEL3_AVG_8_MSRMT 0x03000000 +#define AM_REG_ADC_SL3CFG_ADSEL3_AVG_16_MSRMTS 0x04000000 +#define AM_REG_ADC_SL3CFG_ADSEL3_AVG_32_MSRMTS 0x05000000 +#define AM_REG_ADC_SL3CFG_ADSEL3_AVG_64_MSRMTS 0x06000000 +#define AM_REG_ADC_SL3CFG_ADSEL3_AVG_128_MSRMTS 0x07000000 + +// Set the Precision Mode For Slot. +#define AM_REG_ADC_SL3CFG_PRMODE3_S 16 +#define AM_REG_ADC_SL3CFG_PRMODE3_M 0x00030000 +#define AM_REG_ADC_SL3CFG_PRMODE3(n) (((uint32_t)(n) << 16) & 0x00030000) +#define AM_REG_ADC_SL3CFG_PRMODE3_P14B 0x00000000 +#define AM_REG_ADC_SL3CFG_PRMODE3_P12B 0x00010000 +#define AM_REG_ADC_SL3CFG_PRMODE3_P10B 0x00020000 +#define AM_REG_ADC_SL3CFG_PRMODE3_P8B 0x00030000 + +// Select one of the 14 channel inputs for this slot. +#define AM_REG_ADC_SL3CFG_CHSEL3_S 8 +#define AM_REG_ADC_SL3CFG_CHSEL3_M 0x00000F00 +#define AM_REG_ADC_SL3CFG_CHSEL3(n) (((uint32_t)(n) << 8) & 0x00000F00) +#define AM_REG_ADC_SL3CFG_CHSEL3_SE0 0x00000000 +#define AM_REG_ADC_SL3CFG_CHSEL3_SE1 0x00000100 +#define AM_REG_ADC_SL3CFG_CHSEL3_SE2 0x00000200 +#define AM_REG_ADC_SL3CFG_CHSEL3_SE3 0x00000300 +#define AM_REG_ADC_SL3CFG_CHSEL3_SE4 0x00000400 +#define AM_REG_ADC_SL3CFG_CHSEL3_SE5 0x00000500 +#define AM_REG_ADC_SL3CFG_CHSEL3_SE6 0x00000600 +#define AM_REG_ADC_SL3CFG_CHSEL3_SE7 0x00000700 +#define AM_REG_ADC_SL3CFG_CHSEL3_SE8 0x00000800 +#define AM_REG_ADC_SL3CFG_CHSEL3_SE9 0x00000900 +#define AM_REG_ADC_SL3CFG_CHSEL3_DF0 0x00000A00 +#define AM_REG_ADC_SL3CFG_CHSEL3_DF1 0x00000B00 +#define AM_REG_ADC_SL3CFG_CHSEL3_TEMP 0x00000C00 +#define AM_REG_ADC_SL3CFG_CHSEL3_BATT 0x00000D00 +#define AM_REG_ADC_SL3CFG_CHSEL3_VSS 0x00000E00 + +// This bit enables the window compare function for slot 3. +#define AM_REG_ADC_SL3CFG_WCEN3_S 1 +#define AM_REG_ADC_SL3CFG_WCEN3_M 0x00000002 +#define AM_REG_ADC_SL3CFG_WCEN3(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_ADC_SL3CFG_WCEN3_WCEN 0x00000002 + +// This bit enables slot 3 for ADC conversions. +#define AM_REG_ADC_SL3CFG_SLEN3_S 0 +#define AM_REG_ADC_SL3CFG_SLEN3_M 0x00000001 +#define AM_REG_ADC_SL3CFG_SLEN3(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_ADC_SL3CFG_SLEN3_SLEN 0x00000001 + +//***************************************************************************** +// +// ADC_SL4CFG - Slot 4 Configuration Register +// +//***************************************************************************** +// Select the number of measurements to average in the accumulate divide module +// for this slot. +#define AM_REG_ADC_SL4CFG_ADSEL4_S 24 +#define AM_REG_ADC_SL4CFG_ADSEL4_M 0x07000000 +#define AM_REG_ADC_SL4CFG_ADSEL4(n) (((uint32_t)(n) << 24) & 0x07000000) +#define AM_REG_ADC_SL4CFG_ADSEL4_AVG_1_MSRMT 0x00000000 +#define AM_REG_ADC_SL4CFG_ADSEL4_AVG_2_MSRMTS 0x01000000 +#define AM_REG_ADC_SL4CFG_ADSEL4_AVG_4_MSRMTS 0x02000000 +#define AM_REG_ADC_SL4CFG_ADSEL4_AVG_8_MSRMT 0x03000000 +#define AM_REG_ADC_SL4CFG_ADSEL4_AVG_16_MSRMTS 0x04000000 +#define AM_REG_ADC_SL4CFG_ADSEL4_AVG_32_MSRMTS 0x05000000 +#define AM_REG_ADC_SL4CFG_ADSEL4_AVG_64_MSRMTS 0x06000000 +#define AM_REG_ADC_SL4CFG_ADSEL4_AVG_128_MSRMTS 0x07000000 + +// Set the Precision Mode For Slot. +#define AM_REG_ADC_SL4CFG_PRMODE4_S 16 +#define AM_REG_ADC_SL4CFG_PRMODE4_M 0x00030000 +#define AM_REG_ADC_SL4CFG_PRMODE4(n) (((uint32_t)(n) << 16) & 0x00030000) +#define AM_REG_ADC_SL4CFG_PRMODE4_P14B 0x00000000 +#define AM_REG_ADC_SL4CFG_PRMODE4_P12B 0x00010000 +#define AM_REG_ADC_SL4CFG_PRMODE4_P10B 0x00020000 +#define AM_REG_ADC_SL4CFG_PRMODE4_P8B 0x00030000 + +// Select one of the 14 channel inputs for this slot. +#define AM_REG_ADC_SL4CFG_CHSEL4_S 8 +#define AM_REG_ADC_SL4CFG_CHSEL4_M 0x00000F00 +#define AM_REG_ADC_SL4CFG_CHSEL4(n) (((uint32_t)(n) << 8) & 0x00000F00) +#define AM_REG_ADC_SL4CFG_CHSEL4_SE0 0x00000000 +#define AM_REG_ADC_SL4CFG_CHSEL4_SE1 0x00000100 +#define AM_REG_ADC_SL4CFG_CHSEL4_SE2 0x00000200 +#define AM_REG_ADC_SL4CFG_CHSEL4_SE3 0x00000300 +#define AM_REG_ADC_SL4CFG_CHSEL4_SE4 0x00000400 +#define AM_REG_ADC_SL4CFG_CHSEL4_SE5 0x00000500 +#define AM_REG_ADC_SL4CFG_CHSEL4_SE6 0x00000600 +#define AM_REG_ADC_SL4CFG_CHSEL4_SE7 0x00000700 +#define AM_REG_ADC_SL4CFG_CHSEL4_SE8 0x00000800 +#define AM_REG_ADC_SL4CFG_CHSEL4_SE9 0x00000900 +#define AM_REG_ADC_SL4CFG_CHSEL4_DF0 0x00000A00 +#define AM_REG_ADC_SL4CFG_CHSEL4_DF1 0x00000B00 +#define AM_REG_ADC_SL4CFG_CHSEL4_TEMP 0x00000C00 +#define AM_REG_ADC_SL4CFG_CHSEL4_BATT 0x00000D00 +#define AM_REG_ADC_SL4CFG_CHSEL4_VSS 0x00000E00 + +// This bit enables the window compare function for slot 4. +#define AM_REG_ADC_SL4CFG_WCEN4_S 1 +#define AM_REG_ADC_SL4CFG_WCEN4_M 0x00000002 +#define AM_REG_ADC_SL4CFG_WCEN4(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_ADC_SL4CFG_WCEN4_WCEN 0x00000002 + +// This bit enables slot 4 for ADC conversions. +#define AM_REG_ADC_SL4CFG_SLEN4_S 0 +#define AM_REG_ADC_SL4CFG_SLEN4_M 0x00000001 +#define AM_REG_ADC_SL4CFG_SLEN4(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_ADC_SL4CFG_SLEN4_SLEN 0x00000001 + +//***************************************************************************** +// +// ADC_SL5CFG - Slot 5 Configuration Register +// +//***************************************************************************** +// Select number of measurements to average in the accumulate divide module for +// this slot. +#define AM_REG_ADC_SL5CFG_ADSEL5_S 24 +#define AM_REG_ADC_SL5CFG_ADSEL5_M 0x07000000 +#define AM_REG_ADC_SL5CFG_ADSEL5(n) (((uint32_t)(n) << 24) & 0x07000000) +#define AM_REG_ADC_SL5CFG_ADSEL5_AVG_1_MSRMT 0x00000000 +#define AM_REG_ADC_SL5CFG_ADSEL5_AVG_2_MSRMTS 0x01000000 +#define AM_REG_ADC_SL5CFG_ADSEL5_AVG_4_MSRMTS 0x02000000 +#define AM_REG_ADC_SL5CFG_ADSEL5_AVG_8_MSRMT 0x03000000 +#define AM_REG_ADC_SL5CFG_ADSEL5_AVG_16_MSRMTS 0x04000000 +#define AM_REG_ADC_SL5CFG_ADSEL5_AVG_32_MSRMTS 0x05000000 +#define AM_REG_ADC_SL5CFG_ADSEL5_AVG_64_MSRMTS 0x06000000 +#define AM_REG_ADC_SL5CFG_ADSEL5_AVG_128_MSRMTS 0x07000000 + +// Set the Precision Mode For Slot. +#define AM_REG_ADC_SL5CFG_PRMODE5_S 16 +#define AM_REG_ADC_SL5CFG_PRMODE5_M 0x00030000 +#define AM_REG_ADC_SL5CFG_PRMODE5(n) (((uint32_t)(n) << 16) & 0x00030000) +#define AM_REG_ADC_SL5CFG_PRMODE5_P14B 0x00000000 +#define AM_REG_ADC_SL5CFG_PRMODE5_P12B 0x00010000 +#define AM_REG_ADC_SL5CFG_PRMODE5_P10B 0x00020000 +#define AM_REG_ADC_SL5CFG_PRMODE5_P8B 0x00030000 + +// Select one of the 14 channel inputs for this slot. +#define AM_REG_ADC_SL5CFG_CHSEL5_S 8 +#define AM_REG_ADC_SL5CFG_CHSEL5_M 0x00000F00 +#define AM_REG_ADC_SL5CFG_CHSEL5(n) (((uint32_t)(n) << 8) & 0x00000F00) +#define AM_REG_ADC_SL5CFG_CHSEL5_SE0 0x00000000 +#define AM_REG_ADC_SL5CFG_CHSEL5_SE1 0x00000100 +#define AM_REG_ADC_SL5CFG_CHSEL5_SE2 0x00000200 +#define AM_REG_ADC_SL5CFG_CHSEL5_SE3 0x00000300 +#define AM_REG_ADC_SL5CFG_CHSEL5_SE4 0x00000400 +#define AM_REG_ADC_SL5CFG_CHSEL5_SE5 0x00000500 +#define AM_REG_ADC_SL5CFG_CHSEL5_SE6 0x00000600 +#define AM_REG_ADC_SL5CFG_CHSEL5_SE7 0x00000700 +#define AM_REG_ADC_SL5CFG_CHSEL5_SE8 0x00000800 +#define AM_REG_ADC_SL5CFG_CHSEL5_SE9 0x00000900 +#define AM_REG_ADC_SL5CFG_CHSEL5_DF0 0x00000A00 +#define AM_REG_ADC_SL5CFG_CHSEL5_DF1 0x00000B00 +#define AM_REG_ADC_SL5CFG_CHSEL5_TEMP 0x00000C00 +#define AM_REG_ADC_SL5CFG_CHSEL5_BATT 0x00000D00 +#define AM_REG_ADC_SL5CFG_CHSEL5_VSS 0x00000E00 + +// This bit enables the window compare function for slot 5. +#define AM_REG_ADC_SL5CFG_WCEN5_S 1 +#define AM_REG_ADC_SL5CFG_WCEN5_M 0x00000002 +#define AM_REG_ADC_SL5CFG_WCEN5(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_ADC_SL5CFG_WCEN5_WCEN 0x00000002 + +// This bit enables slot 5 for ADC conversions. +#define AM_REG_ADC_SL5CFG_SLEN5_S 0 +#define AM_REG_ADC_SL5CFG_SLEN5_M 0x00000001 +#define AM_REG_ADC_SL5CFG_SLEN5(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_ADC_SL5CFG_SLEN5_SLEN 0x00000001 + +//***************************************************************************** +// +// ADC_SL6CFG - Slot 6 Configuration Register +// +//***************************************************************************** +// Select the number of measurements to average in the accumulate divide module +// for this slot. +#define AM_REG_ADC_SL6CFG_ADSEL6_S 24 +#define AM_REG_ADC_SL6CFG_ADSEL6_M 0x07000000 +#define AM_REG_ADC_SL6CFG_ADSEL6(n) (((uint32_t)(n) << 24) & 0x07000000) +#define AM_REG_ADC_SL6CFG_ADSEL6_AVG_1_MSRMT 0x00000000 +#define AM_REG_ADC_SL6CFG_ADSEL6_AVG_2_MSRMTS 0x01000000 +#define AM_REG_ADC_SL6CFG_ADSEL6_AVG_4_MSRMTS 0x02000000 +#define AM_REG_ADC_SL6CFG_ADSEL6_AVG_8_MSRMT 0x03000000 +#define AM_REG_ADC_SL6CFG_ADSEL6_AVG_16_MSRMTS 0x04000000 +#define AM_REG_ADC_SL6CFG_ADSEL6_AVG_32_MSRMTS 0x05000000 +#define AM_REG_ADC_SL6CFG_ADSEL6_AVG_64_MSRMTS 0x06000000 +#define AM_REG_ADC_SL6CFG_ADSEL6_AVG_128_MSRMTS 0x07000000 + +// Set the Precision Mode For Slot. +#define AM_REG_ADC_SL6CFG_PRMODE6_S 16 +#define AM_REG_ADC_SL6CFG_PRMODE6_M 0x00030000 +#define AM_REG_ADC_SL6CFG_PRMODE6(n) (((uint32_t)(n) << 16) & 0x00030000) +#define AM_REG_ADC_SL6CFG_PRMODE6_P14B 0x00000000 +#define AM_REG_ADC_SL6CFG_PRMODE6_P12B 0x00010000 +#define AM_REG_ADC_SL6CFG_PRMODE6_P10B 0x00020000 +#define AM_REG_ADC_SL6CFG_PRMODE6_P8B 0x00030000 + +// Select one of the 14 channel inputs for this slot. +#define AM_REG_ADC_SL6CFG_CHSEL6_S 8 +#define AM_REG_ADC_SL6CFG_CHSEL6_M 0x00000F00 +#define AM_REG_ADC_SL6CFG_CHSEL6(n) (((uint32_t)(n) << 8) & 0x00000F00) +#define AM_REG_ADC_SL6CFG_CHSEL6_SE0 0x00000000 +#define AM_REG_ADC_SL6CFG_CHSEL6_SE1 0x00000100 +#define AM_REG_ADC_SL6CFG_CHSEL6_SE2 0x00000200 +#define AM_REG_ADC_SL6CFG_CHSEL6_SE3 0x00000300 +#define AM_REG_ADC_SL6CFG_CHSEL6_SE4 0x00000400 +#define AM_REG_ADC_SL6CFG_CHSEL6_SE5 0x00000500 +#define AM_REG_ADC_SL6CFG_CHSEL6_SE6 0x00000600 +#define AM_REG_ADC_SL6CFG_CHSEL6_SE7 0x00000700 +#define AM_REG_ADC_SL6CFG_CHSEL6_SE8 0x00000800 +#define AM_REG_ADC_SL6CFG_CHSEL6_SE9 0x00000900 +#define AM_REG_ADC_SL6CFG_CHSEL6_DF0 0x00000A00 +#define AM_REG_ADC_SL6CFG_CHSEL6_DF1 0x00000B00 +#define AM_REG_ADC_SL6CFG_CHSEL6_TEMP 0x00000C00 +#define AM_REG_ADC_SL6CFG_CHSEL6_BATT 0x00000D00 +#define AM_REG_ADC_SL6CFG_CHSEL6_VSS 0x00000E00 + +// This bit enables the window compare function for slot 6. +#define AM_REG_ADC_SL6CFG_WCEN6_S 1 +#define AM_REG_ADC_SL6CFG_WCEN6_M 0x00000002 +#define AM_REG_ADC_SL6CFG_WCEN6(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_ADC_SL6CFG_WCEN6_WCEN 0x00000002 + +// This bit enables slot 6 for ADC conversions. +#define AM_REG_ADC_SL6CFG_SLEN6_S 0 +#define AM_REG_ADC_SL6CFG_SLEN6_M 0x00000001 +#define AM_REG_ADC_SL6CFG_SLEN6(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_ADC_SL6CFG_SLEN6_SLEN 0x00000001 + +//***************************************************************************** +// +// ADC_SL7CFG - Slot 7 Configuration Register +// +//***************************************************************************** +// Select the number of measurements to average in the accumulate divide module +// for this slot. +#define AM_REG_ADC_SL7CFG_ADSEL7_S 24 +#define AM_REG_ADC_SL7CFG_ADSEL7_M 0x07000000 +#define AM_REG_ADC_SL7CFG_ADSEL7(n) (((uint32_t)(n) << 24) & 0x07000000) +#define AM_REG_ADC_SL7CFG_ADSEL7_AVG_1_MSRMT 0x00000000 +#define AM_REG_ADC_SL7CFG_ADSEL7_AVG_2_MSRMTS 0x01000000 +#define AM_REG_ADC_SL7CFG_ADSEL7_AVG_4_MSRMTS 0x02000000 +#define AM_REG_ADC_SL7CFG_ADSEL7_AVG_8_MSRMT 0x03000000 +#define AM_REG_ADC_SL7CFG_ADSEL7_AVG_16_MSRMTS 0x04000000 +#define AM_REG_ADC_SL7CFG_ADSEL7_AVG_32_MSRMTS 0x05000000 +#define AM_REG_ADC_SL7CFG_ADSEL7_AVG_64_MSRMTS 0x06000000 +#define AM_REG_ADC_SL7CFG_ADSEL7_AVG_128_MSRMTS 0x07000000 + +// Set the Precision Mode For Slot. +#define AM_REG_ADC_SL7CFG_PRMODE7_S 16 +#define AM_REG_ADC_SL7CFG_PRMODE7_M 0x00030000 +#define AM_REG_ADC_SL7CFG_PRMODE7(n) (((uint32_t)(n) << 16) & 0x00030000) +#define AM_REG_ADC_SL7CFG_PRMODE7_P14B 0x00000000 +#define AM_REG_ADC_SL7CFG_PRMODE7_P12B 0x00010000 +#define AM_REG_ADC_SL7CFG_PRMODE7_P10B 0x00020000 +#define AM_REG_ADC_SL7CFG_PRMODE7_P8B 0x00030000 + +// Select one of the 14 channel inputs for this slot. +#define AM_REG_ADC_SL7CFG_CHSEL7_S 8 +#define AM_REG_ADC_SL7CFG_CHSEL7_M 0x00000F00 +#define AM_REG_ADC_SL7CFG_CHSEL7(n) (((uint32_t)(n) << 8) & 0x00000F00) +#define AM_REG_ADC_SL7CFG_CHSEL7_SE0 0x00000000 +#define AM_REG_ADC_SL7CFG_CHSEL7_SE1 0x00000100 +#define AM_REG_ADC_SL7CFG_CHSEL7_SE2 0x00000200 +#define AM_REG_ADC_SL7CFG_CHSEL7_SE3 0x00000300 +#define AM_REG_ADC_SL7CFG_CHSEL7_SE4 0x00000400 +#define AM_REG_ADC_SL7CFG_CHSEL7_SE5 0x00000500 +#define AM_REG_ADC_SL7CFG_CHSEL7_SE6 0x00000600 +#define AM_REG_ADC_SL7CFG_CHSEL7_SE7 0x00000700 +#define AM_REG_ADC_SL7CFG_CHSEL7_SE8 0x00000800 +#define AM_REG_ADC_SL7CFG_CHSEL7_SE9 0x00000900 +#define AM_REG_ADC_SL7CFG_CHSEL7_DF0 0x00000A00 +#define AM_REG_ADC_SL7CFG_CHSEL7_DF1 0x00000B00 +#define AM_REG_ADC_SL7CFG_CHSEL7_TEMP 0x00000C00 +#define AM_REG_ADC_SL7CFG_CHSEL7_BATT 0x00000D00 +#define AM_REG_ADC_SL7CFG_CHSEL7_VSS 0x00000E00 + +// This bit enables the window compare function for slot 7. +#define AM_REG_ADC_SL7CFG_WCEN7_S 1 +#define AM_REG_ADC_SL7CFG_WCEN7_M 0x00000002 +#define AM_REG_ADC_SL7CFG_WCEN7(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_ADC_SL7CFG_WCEN7_WCEN 0x00000002 + +// This bit enables slot 7 for ADC conversions. +#define AM_REG_ADC_SL7CFG_SLEN7_S 0 +#define AM_REG_ADC_SL7CFG_SLEN7_M 0x00000001 +#define AM_REG_ADC_SL7CFG_SLEN7(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_ADC_SL7CFG_SLEN7_SLEN 0x00000001 + +//***************************************************************************** +// +// ADC_WULIM - Window Comparator Upper Limits Register +// +//***************************************************************************** +// Sets the upper limit for the wondow comparator. +#define AM_REG_ADC_WULIM_ULIM_S 0 +#define AM_REG_ADC_WULIM_ULIM_M 0x000FFFFF +#define AM_REG_ADC_WULIM_ULIM(n) (((uint32_t)(n) << 0) & 0x000FFFFF) + +//***************************************************************************** +// +// ADC_WLLIM - Window Comparator Lower Limits Register +// +//***************************************************************************** +// Sets the lower limit for the wondow comparator. +#define AM_REG_ADC_WLLIM_LLIM_S 0 +#define AM_REG_ADC_WLLIM_LLIM_M 0x000FFFFF +#define AM_REG_ADC_WLLIM_LLIM(n) (((uint32_t)(n) << 0) & 0x000FFFFF) + +//***************************************************************************** +// +// ADC_FIFO - FIFO Data and Valid Count Register +// +//***************************************************************************** +// RESERVED. +#define AM_REG_ADC_FIFO_RSVD_S 31 +#define AM_REG_ADC_FIFO_RSVD_M 0x80000000 +#define AM_REG_ADC_FIFO_RSVD(n) (((uint32_t)(n) << 31) & 0x80000000) + +// Slot number associated with this FIFO data. +#define AM_REG_ADC_FIFO_SLOTNUM_S 28 +#define AM_REG_ADC_FIFO_SLOTNUM_M 0x70000000 +#define AM_REG_ADC_FIFO_SLOTNUM(n) (((uint32_t)(n) << 28) & 0x70000000) + +// Number of valid entries in the ADC FIFO. +#define AM_REG_ADC_FIFO_COUNT_S 20 +#define AM_REG_ADC_FIFO_COUNT_M 0x0FF00000 +#define AM_REG_ADC_FIFO_COUNT(n) (((uint32_t)(n) << 20) & 0x0FF00000) + +// Oldest data in the FIFO. +#define AM_REG_ADC_FIFO_DATA_S 0 +#define AM_REG_ADC_FIFO_DATA_M 0x000FFFFF +#define AM_REG_ADC_FIFO_DATA(n) (((uint32_t)(n) << 0) & 0x000FFFFF) + +#endif // AM_REG_ADC_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_base_addresses.h b/bsp/apollo2/libraries/drivers/regs/am_reg_base_addresses.h new file mode 100644 index 0000000000..13a850d1c4 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_base_addresses.h @@ -0,0 +1,77 @@ +//***************************************************************************** +// +//! @file am_reg_base_addresses.h +//! +//! @brief Register defines for all module base addresses +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_BASE_ADDRESSES_H +#define AM_REG_BASE_ADDRESSES_H + +#include "stdint.h" + +// ARM standard register space (needed for macros) +#define REG_ITM_BASEADDR (0x00000000UL) +#define REG_JEDEC_BASEADDR (0x00000000UL) +#define REG_NVIC_BASEADDR (0x00000000UL) +#define REG_SYSCTRL_BASEADDR (0x00000000UL) +#define REG_SYSTICK_BASEADDR (0x00000000UL) +#define REG_TPIU_BASEADDR (0x00000000UL) + +// Peripheral register space +#define REG_ADC_BASEADDR (0x50010000UL) +#define REG_CACHECTRL_BASEADDR (0x40018000UL) +#define REG_CLKGEN_BASEADDR (0x40004000UL) +#define REG_CTIMER_BASEADDR (0x40008000UL) +#define REG_GPIO_BASEADDR (0x40010000UL) +#define REG_IOMSTR_BASEADDR (0x50004000UL) +#define REG_IOSLAVE_BASEADDR (0x50000000UL) +#define REG_MCUCTRL_BASEADDR (0x40020000UL) +#define REG_PDM_BASEADDR (0x50011000UL) +#define REG_PWRCTRL_BASEADDR (0x40021000UL) +#define REG_RSTGEN_BASEADDR (0x40000000UL) +#define REG_RTC_BASEADDR (0x40004000UL) +#define REG_UART_BASEADDR (0x4001C000UL) +#define REG_VCOMP_BASEADDR (0x4000C000UL) +#define REG_WDT_BASEADDR (0x40024000UL) + +// SRAM address space +#define SRAM_BASEADDR (0x10000000UL) + +#endif // AM_REG_BASE_ADDRESSES_H + diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_cachectrl.h b/bsp/apollo2/libraries/drivers/regs/am_reg_cachectrl.h new file mode 100644 index 0000000000..b933a08874 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_cachectrl.h @@ -0,0 +1,415 @@ +//***************************************************************************** +// +// am_reg_cachectrl.h +//! @file +//! +//! @brief Register macros for the CACHECTRL module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_CACHECTRL_H +#define AM_REG_CACHECTRL_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_CACHECTRL_NUM_MODULES 1 +#define AM_REG_CACHECTRLn(n) \ + (REG_CACHECTRL_BASEADDR + 0x00001000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_CACHECTRL_CACHECFG_O 0x00000000 +#define AM_REG_CACHECTRL_FLASHCFG_O 0x00000004 +#define AM_REG_CACHECTRL_CACHECTRL_O 0x00000008 +#define AM_REG_CACHECTRL_NCR0START_O 0x00000010 +#define AM_REG_CACHECTRL_NCR0END_O 0x00000014 +#define AM_REG_CACHECTRL_NCR1START_O 0x00000018 +#define AM_REG_CACHECTRL_NCR1END_O 0x0000001C +#define AM_REG_CACHECTRL_CACHEMODE_O 0x00000030 +#define AM_REG_CACHECTRL_DMON0_O 0x00000040 +#define AM_REG_CACHECTRL_DMON1_O 0x00000044 +#define AM_REG_CACHECTRL_DMON2_O 0x00000048 +#define AM_REG_CACHECTRL_DMON3_O 0x0000004C +#define AM_REG_CACHECTRL_IMON0_O 0x00000050 +#define AM_REG_CACHECTRL_IMON1_O 0x00000054 +#define AM_REG_CACHECTRL_IMON2_O 0x00000058 +#define AM_REG_CACHECTRL_IMON3_O 0x0000005C + +//***************************************************************************** +// +// CACHECTRL_CACHECFG - Flash Cache Control Register +// +//***************************************************************************** +// Enable Cache Monitoring Stats. Only enable this for debug/performance +// analysis since it will consume additional power. See IMON/DMON registers for +// data. +#define AM_REG_CACHECTRL_CACHECFG_ENABLE_MONITOR_S 24 +#define AM_REG_CACHECTRL_CACHECFG_ENABLE_MONITOR_M 0x01000000 +#define AM_REG_CACHECTRL_CACHECFG_ENABLE_MONITOR(n) (((uint32_t)(n) << 24) & 0x01000000) + +// Enable clock gating of entire cache data array subsystem. This should be +// enabled for normal operation. +#define AM_REG_CACHECTRL_CACHECFG_DATA_CLKGATE_S 20 +#define AM_REG_CACHECTRL_CACHECFG_DATA_CLKGATE_M 0x00100000 +#define AM_REG_CACHECTRL_CACHECFG_DATA_CLKGATE(n) (((uint32_t)(n) << 20) & 0x00100000) + +// Unused. Should be left at default value. +#define AM_REG_CACHECTRL_CACHECFG_SMDLY_S 16 +#define AM_REG_CACHECTRL_CACHECFG_SMDLY_M 0x000F0000 +#define AM_REG_CACHECTRL_CACHECFG_SMDLY(n) (((uint32_t)(n) << 16) & 0x000F0000) + +// Unused. Should be left at default value. +#define AM_REG_CACHECTRL_CACHECFG_DLY_S 12 +#define AM_REG_CACHECTRL_CACHECFG_DLY_M 0x0000F000 +#define AM_REG_CACHECTRL_CACHECFG_DLY(n) (((uint32_t)(n) << 12) & 0x0000F000) + +// Enable LS (light sleep) of cache RAMs. This should not be enabled for normal +// operation. When this bit is set, the cache's RAMS will be put into light +// sleep mode while inactive. NOTE: if the cache is actively used, this may +// have an adverse affect on power since entering/exiting LS mode may consume +// more power than would be saved. +#define AM_REG_CACHECTRL_CACHECFG_CACHE_LS_S 11 +#define AM_REG_CACHECTRL_CACHECFG_CACHE_LS_M 0x00000800 +#define AM_REG_CACHECTRL_CACHECFG_CACHE_LS(n) (((uint32_t)(n) << 11) & 0x00000800) + +// Enable clock gating of individual cache RAMs. This bit should be enabled for +// normal operation for lowest power consumption. +#define AM_REG_CACHECTRL_CACHECFG_CACHE_CLKGATE_S 10 +#define AM_REG_CACHECTRL_CACHECFG_CACHE_CLKGATE_M 0x00000400 +#define AM_REG_CACHECTRL_CACHECFG_CACHE_CLKGATE(n) (((uint32_t)(n) << 10) & 0x00000400) + +// Enable Flash Data Caching. When set to 1, all instruction accesses to flash +// will be cached. +#define AM_REG_CACHECTRL_CACHECFG_DCACHE_ENABLE_S 9 +#define AM_REG_CACHECTRL_CACHECFG_DCACHE_ENABLE_M 0x00000200 +#define AM_REG_CACHECTRL_CACHECFG_DCACHE_ENABLE(n) (((uint32_t)(n) << 9) & 0x00000200) + +// Enable Flash Instruction Caching. When set to 1, all instruction accesses to +// flash will be cached. +#define AM_REG_CACHECTRL_CACHECFG_ICACHE_ENABLE_S 8 +#define AM_REG_CACHECTRL_CACHECFG_ICACHE_ENABLE_M 0x00000100 +#define AM_REG_CACHECTRL_CACHECFG_ICACHE_ENABLE(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Bitfield should always be programmed to 0. +#define AM_REG_CACHECTRL_CACHECFG_SERIAL_S 7 +#define AM_REG_CACHECTRL_CACHECFG_SERIAL_M 0x00000080 +#define AM_REG_CACHECTRL_CACHECFG_SERIAL(n) (((uint32_t)(n) << 7) & 0x00000080) + +// Sets the cache configuration. Only a single configuration of 0x5 is valid. +#define AM_REG_CACHECTRL_CACHECFG_CONFIG_S 4 +#define AM_REG_CACHECTRL_CACHECFG_CONFIG_M 0x00000070 +#define AM_REG_CACHECTRL_CACHECFG_CONFIG(n) (((uint32_t)(n) << 4) & 0x00000070) +#define AM_REG_CACHECTRL_CACHECFG_CONFIG_W2_128B_512E 0x00000050 + +// Enable Non-cacheable region 1. See the NCR1 registers to set the region +// boundaries and size. +#define AM_REG_CACHECTRL_CACHECFG_ENABLE_NC1_S 3 +#define AM_REG_CACHECTRL_CACHECFG_ENABLE_NC1_M 0x00000008 +#define AM_REG_CACHECTRL_CACHECFG_ENABLE_NC1(n) (((uint32_t)(n) << 3) & 0x00000008) + +// Enable Non-cacheable region 0. See the NCR0 registers to set the region +// boundaries and size. +#define AM_REG_CACHECTRL_CACHECFG_ENABLE_NC0_S 2 +#define AM_REG_CACHECTRL_CACHECFG_ENABLE_NC0_M 0x00000004 +#define AM_REG_CACHECTRL_CACHECFG_ENABLE_NC0(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Sets the cache replacement policy. 0=LRR (least recently replaced), 1=LRU +// (least recently used). LRR minimizes writes to the TAG SRAM and is +// recommended. +#define AM_REG_CACHECTRL_CACHECFG_LRU_S 1 +#define AM_REG_CACHECTRL_CACHECFG_LRU_M 0x00000002 +#define AM_REG_CACHECTRL_CACHECFG_LRU(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Enables the main flash cache controller logic and enables power to the cache +// RAMs. Instruction and Data caching need to be enabled independently using +// the ICACHE_ENABLE and DCACHE_ENABLE bits. +#define AM_REG_CACHECTRL_CACHECFG_ENABLE_S 0 +#define AM_REG_CACHECTRL_CACHECFG_ENABLE_M 0x00000001 +#define AM_REG_CACHECTRL_CACHECFG_ENABLE(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// CACHECTRL_FLASHCFG - Flash Control Register +// +//***************************************************************************** +// Sets read waitstates for flash accesses (in clock cycles). This should be +// left at the default value for normal flash operation. +#define AM_REG_CACHECTRL_FLASHCFG_RD_WAIT_S 0 +#define AM_REG_CACHECTRL_FLASHCFG_RD_WAIT_M 0x00000007 +#define AM_REG_CACHECTRL_FLASHCFG_RD_WAIT(n) (((uint32_t)(n) << 0) & 0x00000007) + +//***************************************************************************** +// +// CACHECTRL_CACHECTRL - Cache Control +// +//***************************************************************************** +// Enable Flash Sleep Mode. After writing this bit, the flash instance 1 will +// enter a low-power mode until the CPU writes the SLM_DISABLE bit or a flash +// access occurs. Wake from SLM requires ~5us, so this should only be set if +// the flash will not be accessed for reasonably long time. +#define AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_ENABLE_S 10 +#define AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_ENABLE_M 0x00000400 +#define AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_ENABLE(n) (((uint32_t)(n) << 10) & 0x00000400) + +// Disable Flash Sleep Mode. Allows CPU to manually disable SLM mode. +// Performing a flash read will also wake the array. +#define AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_DISABLE_S 9 +#define AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_DISABLE_M 0x00000200 +#define AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_DISABLE(n) (((uint32_t)(n) << 9) & 0x00000200) + +// Flash Sleep Mode Status. When 1, flash instance 1 is asleep. +#define AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_STATUS_S 8 +#define AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_STATUS_M 0x00000100 +#define AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_STATUS(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Enable Flash Sleep Mode. After writing this bit, the flash instance 0 will +// enter a low-power mode until the CPU writes the SLM_DISABLE bit or a flash +// access occurs. Wake from SLM requires ~5us, so this should only be set if +// the flash will not be accessed for reasonably long time. +#define AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_ENABLE_S 6 +#define AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_ENABLE_M 0x00000040 +#define AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_ENABLE(n) (((uint32_t)(n) << 6) & 0x00000040) + +// Disable Flash Sleep Mode. Allows CPU to manually disable SLM mode. +// Performing a flash read will also wake the array. +#define AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_DISABLE_S 5 +#define AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_DISABLE_M 0x00000020 +#define AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_DISABLE(n) (((uint32_t)(n) << 5) & 0x00000020) + +// Flash Sleep Mode Status. When 1, flash instance 0 is asleep. +#define AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_STATUS_S 4 +#define AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_STATUS_M 0x00000010 +#define AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_STATUS(n) (((uint32_t)(n) << 4) & 0x00000010) + +// Cache Ready Status. A value of 1 indicates the cache is enabled and not +// processing an invalidate operation. +#define AM_REG_CACHECTRL_CACHECTRL_CACHE_READY_S 2 +#define AM_REG_CACHECTRL_CACHECTRL_CACHE_READY_M 0x00000004 +#define AM_REG_CACHECTRL_CACHECTRL_CACHE_READY(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Writing a 1 to this bitfield will reset the cache monitor statistics +// (DMON0-3, IMON0-3). Statistic gathering can be paused/stopped by disabling +// the MONITOR_ENABLE bit in CACHECFG, which will maintain the count values +// until the stats are reset by writing this bitfield. +#define AM_REG_CACHECTRL_CACHECTRL_RESET_STAT_S 1 +#define AM_REG_CACHECTRL_CACHECTRL_RESET_STAT_M 0x00000002 +#define AM_REG_CACHECTRL_CACHECTRL_RESET_STAT(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_CACHECTRL_CACHECTRL_RESET_STAT_CLEAR 0x00000002 + +// Writing a 1 to this bitfield invalidates the flash cache contents. +#define AM_REG_CACHECTRL_CACHECTRL_INVALIDATE_S 0 +#define AM_REG_CACHECTRL_CACHECTRL_INVALIDATE_M 0x00000001 +#define AM_REG_CACHECTRL_CACHECTRL_INVALIDATE(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_CACHECTRL_CACHECTRL_INVALIDATE_GO 0x00000001 + +//***************************************************************************** +// +// CACHECTRL_NCR0START - Flash Cache Noncachable Region 0 Start Address. +// +//***************************************************************************** +// Start address for non-cacheable region 0. The physical address of the start +// of this region should be programmed to this register and must be aligned to a +// 16-byte boundary (thus the lower 4 address bits are unused). +#define AM_REG_CACHECTRL_NCR0START_ADDR_S 4 +#define AM_REG_CACHECTRL_NCR0START_ADDR_M 0x000FFFF0 +#define AM_REG_CACHECTRL_NCR0START_ADDR(n) (((uint32_t)(n) << 4) & 0x000FFFF0) + +//***************************************************************************** +// +// CACHECTRL_NCR0END - Flash Cache Noncachable Region 0 End +// +//***************************************************************************** +// End address for non-cacheable region 0. The physical address of the end of +// this region should be programmed to this register and must be aligned to a +// 16-byte boundary (thus the lower 4 address bits are unused). +#define AM_REG_CACHECTRL_NCR0END_ADDR_S 4 +#define AM_REG_CACHECTRL_NCR0END_ADDR_M 0x000FFFF0 +#define AM_REG_CACHECTRL_NCR0END_ADDR(n) (((uint32_t)(n) << 4) & 0x000FFFF0) + +//***************************************************************************** +// +// CACHECTRL_NCR1START - Flash Cache Noncachable Region 1 Start +// +//***************************************************************************** +// Start address for non-cacheable region 1. The physical address of the start +// of this region should be programmed to this register and must be aligned to a +// 16-byte boundary (thus the lower 4 address bits are unused). +#define AM_REG_CACHECTRL_NCR1START_ADDR_S 4 +#define AM_REG_CACHECTRL_NCR1START_ADDR_M 0x000FFFF0 +#define AM_REG_CACHECTRL_NCR1START_ADDR(n) (((uint32_t)(n) << 4) & 0x000FFFF0) + +//***************************************************************************** +// +// CACHECTRL_NCR1END - Flash Cache Noncachable Region 1 End +// +//***************************************************************************** +// End address for non-cacheable region 1. The physical address of the end of +// this region should be programmed to this register and must be aligned to a +// 16-byte boundary (thus the lower 4 address bits are unused). +#define AM_REG_CACHECTRL_NCR1END_ADDR_S 4 +#define AM_REG_CACHECTRL_NCR1END_ADDR_M 0x000FFFF0 +#define AM_REG_CACHECTRL_NCR1END_ADDR(n) (((uint32_t)(n) << 4) & 0x000FFFF0) + +//***************************************************************************** +// +// CACHECTRL_CACHEMODE - Flash Cache Mode Register. Used to trim +// performance/power. +// +//***************************************************************************** +// Disallow Simultaneous Data RAM reads (from 2 line hits on each bus). Value +// should be left at zero for optimal performance. +#define AM_REG_CACHECTRL_CACHEMODE_THROTTLE6_S 5 +#define AM_REG_CACHECTRL_CACHEMODE_THROTTLE6_M 0x00000020 +#define AM_REG_CACHECTRL_CACHEMODE_THROTTLE6(n) (((uint32_t)(n) << 5) & 0x00000020) + +// Disallow Data RAM reads (from line hits) during lookup read ops. Value +// should be left at zero for optimal performance. +#define AM_REG_CACHECTRL_CACHEMODE_THROTTLE5_S 4 +#define AM_REG_CACHECTRL_CACHEMODE_THROTTLE5_M 0x00000010 +#define AM_REG_CACHECTRL_CACHEMODE_THROTTLE5(n) (((uint32_t)(n) << 4) & 0x00000010) + +// Disallow Data RAM reads (from line hits) on tag RAM fill cycles. Value should +// be left at zero for optimal performance. +#define AM_REG_CACHECTRL_CACHEMODE_THROTTLE4_S 3 +#define AM_REG_CACHECTRL_CACHEMODE_THROTTLE4_M 0x00000008 +#define AM_REG_CACHECTRL_CACHEMODE_THROTTLE4(n) (((uint32_t)(n) << 3) & 0x00000008) + +// Disallow cache data RAM writes on data RAM read cycles. Value should be left +// at zero for optimal performance. +#define AM_REG_CACHECTRL_CACHEMODE_THROTTLE3_S 2 +#define AM_REG_CACHECTRL_CACHEMODE_THROTTLE3_M 0x00000004 +#define AM_REG_CACHECTRL_CACHEMODE_THROTTLE3(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Disallow cache data RAM writes on tag RAM read cycles. Value should be left +// at zero for optimal performance. +#define AM_REG_CACHECTRL_CACHEMODE_THROTTLE2_S 1 +#define AM_REG_CACHECTRL_CACHEMODE_THROTTLE2_M 0x00000002 +#define AM_REG_CACHECTRL_CACHEMODE_THROTTLE2(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Disallow cache data RAM writes on tag RAM fill cycles. Value should be left +// at zero for optimal performance. +#define AM_REG_CACHECTRL_CACHEMODE_THROTTLE1_S 0 +#define AM_REG_CACHECTRL_CACHEMODE_THROTTLE1_M 0x00000001 +#define AM_REG_CACHECTRL_CACHEMODE_THROTTLE1(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// CACHECTRL_DMON0 - Data Cache Total Accesses +// +//***************************************************************************** +// Total accesses to data cache +#define AM_REG_CACHECTRL_DMON0_DACCESS_COUNT_S 0 +#define AM_REG_CACHECTRL_DMON0_DACCESS_COUNT_M 0xFFFFFFFF +#define AM_REG_CACHECTRL_DMON0_DACCESS_COUNT(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CACHECTRL_DMON1 - Data Cache Tag Lookups +// +//***************************************************************************** +// Total tag lookups from data cache +#define AM_REG_CACHECTRL_DMON1_DLOOKUP_COUNT_S 0 +#define AM_REG_CACHECTRL_DMON1_DLOOKUP_COUNT_M 0xFFFFFFFF +#define AM_REG_CACHECTRL_DMON1_DLOOKUP_COUNT(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CACHECTRL_DMON2 - Data Cache Hits +// +//***************************************************************************** +// Cache hits from lookup operations +#define AM_REG_CACHECTRL_DMON2_DHIT_COUNT_S 0 +#define AM_REG_CACHECTRL_DMON2_DHIT_COUNT_M 0xFFFFFFFF +#define AM_REG_CACHECTRL_DMON2_DHIT_COUNT(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CACHECTRL_DMON3 - Data Cache Line Hits +// +//***************************************************************************** +// Cache hits from line cache +#define AM_REG_CACHECTRL_DMON3_DLINE_COUNT_S 0 +#define AM_REG_CACHECTRL_DMON3_DLINE_COUNT_M 0xFFFFFFFF +#define AM_REG_CACHECTRL_DMON3_DLINE_COUNT(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CACHECTRL_IMON0 - Instruction Cache Total Accesses +// +//***************************************************************************** +// Total accesses to Instruction cache +#define AM_REG_CACHECTRL_IMON0_IACCESS_COUNT_S 0 +#define AM_REG_CACHECTRL_IMON0_IACCESS_COUNT_M 0xFFFFFFFF +#define AM_REG_CACHECTRL_IMON0_IACCESS_COUNT(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CACHECTRL_IMON1 - Instruction Cache Tag Lookups +// +//***************************************************************************** +// Total tag lookups from Instruction cache +#define AM_REG_CACHECTRL_IMON1_ILOOKUP_COUNT_S 0 +#define AM_REG_CACHECTRL_IMON1_ILOOKUP_COUNT_M 0xFFFFFFFF +#define AM_REG_CACHECTRL_IMON1_ILOOKUP_COUNT(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CACHECTRL_IMON2 - Instruction Cache Hits +// +//***************************************************************************** +// Cache hits from lookup operations +#define AM_REG_CACHECTRL_IMON2_IHIT_COUNT_S 0 +#define AM_REG_CACHECTRL_IMON2_IHIT_COUNT_M 0xFFFFFFFF +#define AM_REG_CACHECTRL_IMON2_IHIT_COUNT(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CACHECTRL_IMON3 - Instruction Cache Line Hits +// +//***************************************************************************** +// Cache hits from line cache +#define AM_REG_CACHECTRL_IMON3_ILINE_COUNT_S 0 +#define AM_REG_CACHECTRL_IMON3_ILINE_COUNT_M 0xFFFFFFFF +#define AM_REG_CACHECTRL_IMON3_ILINE_COUNT(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +#endif // AM_REG_CACHECTRL_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_clkgen.h b/bsp/apollo2/libraries/drivers/regs/am_reg_clkgen.h new file mode 100644 index 0000000000..c769673d65 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_clkgen.h @@ -0,0 +1,501 @@ +//***************************************************************************** +// +// am_reg_clkgen.h +//! @file +//! +//! @brief Register macros for the CLKGEN module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_CLKGEN_H +#define AM_REG_CLKGEN_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_CLKGEN_NUM_MODULES 1 +#define AM_REG_CLKGENn(n) \ + (REG_CLKGEN_BASEADDR + 0x00000000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_CLKGEN_CALXT_O 0x00000000 +#define AM_REG_CLKGEN_CALRC_O 0x00000004 +#define AM_REG_CLKGEN_ACALCTR_O 0x00000008 +#define AM_REG_CLKGEN_OCTRL_O 0x0000000C +#define AM_REG_CLKGEN_CLKOUT_O 0x00000010 +#define AM_REG_CLKGEN_CCTRL_O 0x00000018 +#define AM_REG_CLKGEN_STATUS_O 0x0000001C +#define AM_REG_CLKGEN_HFADJ_O 0x00000020 +#define AM_REG_CLKGEN_HFVAL_O 0x00000024 +#define AM_REG_CLKGEN_CLOCKEN_O 0x00000028 +#define AM_REG_CLKGEN_CLOCKEN2_O 0x0000002C +#define AM_REG_CLKGEN_CLOCKEN3_O 0x00000030 +#define AM_REG_CLKGEN_UARTEN_O 0x00000034 +#define AM_REG_CLKGEN_CLKKEY_O 0x00000014 +#define AM_REG_CLKGEN_INTEN_O 0x00000100 +#define AM_REG_CLKGEN_INTSTAT_O 0x00000104 +#define AM_REG_CLKGEN_INTCLR_O 0x00000108 +#define AM_REG_CLKGEN_INTSET_O 0x0000010C + +//***************************************************************************** +// +// Key values. +// +//***************************************************************************** +#define AM_REG_CLKGEN_CLKKEY_KEYVAL 0x00000047 + +//***************************************************************************** +// +// CLKGEN_INTEN - CLKGEN Interrupt Register: Enable +// +//***************************************************************************** +// RTC Alarm interrupt +#define AM_REG_CLKGEN_INTEN_ALM_S 3 +#define AM_REG_CLKGEN_INTEN_ALM_M 0x00000008 +#define AM_REG_CLKGEN_INTEN_ALM(n) (((uint32_t)(n) << 3) & 0x00000008) + +// XT Oscillator Fail interrupt +#define AM_REG_CLKGEN_INTEN_OF_S 2 +#define AM_REG_CLKGEN_INTEN_OF_M 0x00000004 +#define AM_REG_CLKGEN_INTEN_OF(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Autocalibration Complete interrupt +#define AM_REG_CLKGEN_INTEN_ACC_S 1 +#define AM_REG_CLKGEN_INTEN_ACC_M 0x00000002 +#define AM_REG_CLKGEN_INTEN_ACC(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Autocalibration Fail interrupt +#define AM_REG_CLKGEN_INTEN_ACF_S 0 +#define AM_REG_CLKGEN_INTEN_ACF_M 0x00000001 +#define AM_REG_CLKGEN_INTEN_ACF(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// CLKGEN_INTSTAT - CLKGEN Interrupt Register: Status +// +//***************************************************************************** +// RTC Alarm interrupt +#define AM_REG_CLKGEN_INTSTAT_ALM_S 3 +#define AM_REG_CLKGEN_INTSTAT_ALM_M 0x00000008 +#define AM_REG_CLKGEN_INTSTAT_ALM(n) (((uint32_t)(n) << 3) & 0x00000008) + +// XT Oscillator Fail interrupt +#define AM_REG_CLKGEN_INTSTAT_OF_S 2 +#define AM_REG_CLKGEN_INTSTAT_OF_M 0x00000004 +#define AM_REG_CLKGEN_INTSTAT_OF(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Autocalibration Complete interrupt +#define AM_REG_CLKGEN_INTSTAT_ACC_S 1 +#define AM_REG_CLKGEN_INTSTAT_ACC_M 0x00000002 +#define AM_REG_CLKGEN_INTSTAT_ACC(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Autocalibration Fail interrupt +#define AM_REG_CLKGEN_INTSTAT_ACF_S 0 +#define AM_REG_CLKGEN_INTSTAT_ACF_M 0x00000001 +#define AM_REG_CLKGEN_INTSTAT_ACF(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// CLKGEN_INTCLR - CLKGEN Interrupt Register: Clear +// +//***************************************************************************** +// RTC Alarm interrupt +#define AM_REG_CLKGEN_INTCLR_ALM_S 3 +#define AM_REG_CLKGEN_INTCLR_ALM_M 0x00000008 +#define AM_REG_CLKGEN_INTCLR_ALM(n) (((uint32_t)(n) << 3) & 0x00000008) + +// XT Oscillator Fail interrupt +#define AM_REG_CLKGEN_INTCLR_OF_S 2 +#define AM_REG_CLKGEN_INTCLR_OF_M 0x00000004 +#define AM_REG_CLKGEN_INTCLR_OF(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Autocalibration Complete interrupt +#define AM_REG_CLKGEN_INTCLR_ACC_S 1 +#define AM_REG_CLKGEN_INTCLR_ACC_M 0x00000002 +#define AM_REG_CLKGEN_INTCLR_ACC(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Autocalibration Fail interrupt +#define AM_REG_CLKGEN_INTCLR_ACF_S 0 +#define AM_REG_CLKGEN_INTCLR_ACF_M 0x00000001 +#define AM_REG_CLKGEN_INTCLR_ACF(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// CLKGEN_INTSET - CLKGEN Interrupt Register: Set +// +//***************************************************************************** +// RTC Alarm interrupt +#define AM_REG_CLKGEN_INTSET_ALM_S 3 +#define AM_REG_CLKGEN_INTSET_ALM_M 0x00000008 +#define AM_REG_CLKGEN_INTSET_ALM(n) (((uint32_t)(n) << 3) & 0x00000008) + +// XT Oscillator Fail interrupt +#define AM_REG_CLKGEN_INTSET_OF_S 2 +#define AM_REG_CLKGEN_INTSET_OF_M 0x00000004 +#define AM_REG_CLKGEN_INTSET_OF(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Autocalibration Complete interrupt +#define AM_REG_CLKGEN_INTSET_ACC_S 1 +#define AM_REG_CLKGEN_INTSET_ACC_M 0x00000002 +#define AM_REG_CLKGEN_INTSET_ACC(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Autocalibration Fail interrupt +#define AM_REG_CLKGEN_INTSET_ACF_S 0 +#define AM_REG_CLKGEN_INTSET_ACF_M 0x00000001 +#define AM_REG_CLKGEN_INTSET_ACF(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// CLKGEN_CALXT - XT Oscillator Control +// +//***************************************************************************** +// XT Oscillator calibration value +#define AM_REG_CLKGEN_CALXT_CALXT_S 0 +#define AM_REG_CLKGEN_CALXT_CALXT_M 0x000007FF +#define AM_REG_CLKGEN_CALXT_CALXT(n) (((uint32_t)(n) << 0) & 0x000007FF) + +//***************************************************************************** +// +// CLKGEN_CALRC - RC Oscillator Control +// +//***************************************************************************** +// LFRC Oscillator calibration value +#define AM_REG_CLKGEN_CALRC_CALRC_S 0 +#define AM_REG_CLKGEN_CALRC_CALRC_M 0x0003FFFF +#define AM_REG_CLKGEN_CALRC_CALRC(n) (((uint32_t)(n) << 0) & 0x0003FFFF) + +//***************************************************************************** +// +// CLKGEN_ACALCTR - Autocalibration Counter +// +//***************************************************************************** +// Autocalibration Counter result. +#define AM_REG_CLKGEN_ACALCTR_ACALCTR_S 0 +#define AM_REG_CLKGEN_ACALCTR_ACALCTR_M 0x00FFFFFF +#define AM_REG_CLKGEN_ACALCTR_ACALCTR(n) (((uint32_t)(n) << 0) & 0x00FFFFFF) + +//***************************************************************************** +// +// CLKGEN_OCTRL - Oscillator Control +// +//***************************************************************************** +// Autocalibration control +#define AM_REG_CLKGEN_OCTRL_ACAL_S 8 +#define AM_REG_CLKGEN_OCTRL_ACAL_M 0x00000700 +#define AM_REG_CLKGEN_OCTRL_ACAL(n) (((uint32_t)(n) << 8) & 0x00000700) +#define AM_REG_CLKGEN_OCTRL_ACAL_DIS 0x00000000 +#define AM_REG_CLKGEN_OCTRL_ACAL_1024SEC 0x00000200 +#define AM_REG_CLKGEN_OCTRL_ACAL_512SEC 0x00000300 +#define AM_REG_CLKGEN_OCTRL_ACAL_XTFREQ 0x00000600 +#define AM_REG_CLKGEN_OCTRL_ACAL_EXTFREQ 0x00000700 + +// Selects the RTC oscillator (1 => LFRC, 0 => XT) +#define AM_REG_CLKGEN_OCTRL_OSEL_S 7 +#define AM_REG_CLKGEN_OCTRL_OSEL_M 0x00000080 +#define AM_REG_CLKGEN_OCTRL_OSEL(n) (((uint32_t)(n) << 7) & 0x00000080) +#define AM_REG_CLKGEN_OCTRL_OSEL_RTC_XT 0x00000000 +#define AM_REG_CLKGEN_OCTRL_OSEL_RTC_LFRC 0x00000080 + +// Oscillator switch on failure function +#define AM_REG_CLKGEN_OCTRL_FOS_S 6 +#define AM_REG_CLKGEN_OCTRL_FOS_M 0x00000040 +#define AM_REG_CLKGEN_OCTRL_FOS(n) (((uint32_t)(n) << 6) & 0x00000040) +#define AM_REG_CLKGEN_OCTRL_FOS_DIS 0x00000000 +#define AM_REG_CLKGEN_OCTRL_FOS_EN 0x00000040 + +// Stop the LFRC Oscillator to the RTC +#define AM_REG_CLKGEN_OCTRL_STOPRC_S 1 +#define AM_REG_CLKGEN_OCTRL_STOPRC_M 0x00000002 +#define AM_REG_CLKGEN_OCTRL_STOPRC(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_CLKGEN_OCTRL_STOPRC_EN 0x00000000 +#define AM_REG_CLKGEN_OCTRL_STOPRC_STOP 0x00000002 + +// Stop the XT Oscillator to the RTC +#define AM_REG_CLKGEN_OCTRL_STOPXT_S 0 +#define AM_REG_CLKGEN_OCTRL_STOPXT_M 0x00000001 +#define AM_REG_CLKGEN_OCTRL_STOPXT(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_CLKGEN_OCTRL_STOPXT_EN 0x00000000 +#define AM_REG_CLKGEN_OCTRL_STOPXT_STOP 0x00000001 + +//***************************************************************************** +// +// CLKGEN_CLKOUT - CLKOUT Frequency Select +// +//***************************************************************************** +// Enable the CLKOUT signal +#define AM_REG_CLKGEN_CLKOUT_CKEN_S 7 +#define AM_REG_CLKGEN_CLKOUT_CKEN_M 0x00000080 +#define AM_REG_CLKGEN_CLKOUT_CKEN(n) (((uint32_t)(n) << 7) & 0x00000080) +#define AM_REG_CLKGEN_CLKOUT_CKEN_DIS 0x00000000 +#define AM_REG_CLKGEN_CLKOUT_CKEN_EN 0x00000080 + +// CLKOUT signal select. Note that HIGH_DRIVE should be selected if any high +// frequencies (such as from HFRC) are selected for CLKOUT. +#define AM_REG_CLKGEN_CLKOUT_CKSEL_S 0 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_M 0x0000003F +#define AM_REG_CLKGEN_CLKOUT_CKSEL(n) (((uint32_t)(n) << 0) & 0x0000003F) +#define AM_REG_CLKGEN_CLKOUT_CKSEL_LFRC 0x00000000 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_XT_DIV2 0x00000001 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_XT_DIV4 0x00000002 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_XT_DIV8 0x00000003 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_XT_DIV16 0x00000004 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_XT_DIV32 0x00000005 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_RTC_1Hz 0x00000010 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_XT_DIV2M 0x00000016 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_XT 0x00000017 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_CG_100Hz 0x00000018 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC 0x00000019 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC_DIV4 0x0000001A +#define AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC_DIV8 0x0000001B +#define AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC_DIV16 0x0000001C +#define AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC_DIV64 0x0000001D +#define AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC_DIV128 0x0000001E +#define AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC_DIV256 0x0000001F +#define AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC_DIV512 0x00000020 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_FLASH_CLK 0x00000022 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_LFRC_DIV2 0x00000023 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_LFRC_DIV32 0x00000024 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_LFRC_DIV512 0x00000025 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_LFRC_DIV32K 0x00000026 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_XT_DIV256 0x00000027 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_XT_DIV8K 0x00000028 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_XT_DIV64K 0x00000029 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_ULFRC_DIV16 0x0000002A +#define AM_REG_CLKGEN_CLKOUT_CKSEL_ULFRC_DIV128 0x0000002B +#define AM_REG_CLKGEN_CLKOUT_CKSEL_ULFRC_1Hz 0x0000002C +#define AM_REG_CLKGEN_CLKOUT_CKSEL_ULFRC_DIV4K 0x0000002D +#define AM_REG_CLKGEN_CLKOUT_CKSEL_ULFRC_DIV1M 0x0000002E +#define AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC_DIV64K 0x0000002F +#define AM_REG_CLKGEN_CLKOUT_CKSEL_HFRC_DIV16M 0x00000030 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_LFRC_DIV2M 0x00000031 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_HFRCNE 0x00000032 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_HFRCNE_DIV8 0x00000033 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_XTNE 0x00000035 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_XTNE_DIV16 0x00000036 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_LFRCNE_DIV32 0x00000037 +#define AM_REG_CLKGEN_CLKOUT_CKSEL_LFRCNE 0x00000039 + +//***************************************************************************** +// +// CLKGEN_CCTRL - HFRC Clock Control +// +//***************************************************************************** +// Core Clock divisor +#define AM_REG_CLKGEN_CCTRL_CORESEL_S 0 +#define AM_REG_CLKGEN_CCTRL_CORESEL_M 0x00000001 +#define AM_REG_CLKGEN_CCTRL_CORESEL(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_CLKGEN_CCTRL_CORESEL_HFRC 0x00000000 +#define AM_REG_CLKGEN_CCTRL_CORESEL_HFRC_DIV2 0x00000001 + +//***************************************************************************** +// +// CLKGEN_STATUS - Clock Generator Status +// +//***************************************************************************** +// XT Oscillator is enabled but not oscillating +#define AM_REG_CLKGEN_STATUS_OSCF_S 1 +#define AM_REG_CLKGEN_STATUS_OSCF_M 0x00000002 +#define AM_REG_CLKGEN_STATUS_OSCF(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Current RTC oscillator (1 => LFRC, 0 => XT) +#define AM_REG_CLKGEN_STATUS_OMODE_S 0 +#define AM_REG_CLKGEN_STATUS_OMODE_M 0x00000001 +#define AM_REG_CLKGEN_STATUS_OMODE(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// CLKGEN_HFADJ - HFRC Adjustment +// +//***************************************************************************** +// Gain control for HFRC adjustment +#define AM_REG_CLKGEN_HFADJ_HFADJ_GAIN_S 21 +#define AM_REG_CLKGEN_HFADJ_HFADJ_GAIN_M 0x00E00000 +#define AM_REG_CLKGEN_HFADJ_HFADJ_GAIN(n) (((uint32_t)(n) << 21) & 0x00E00000) +#define AM_REG_CLKGEN_HFADJ_HFADJ_GAIN_Gain_of_1 0x00000000 +#define AM_REG_CLKGEN_HFADJ_HFADJ_GAIN_Gain_of_1_in_2 0x00200000 +#define AM_REG_CLKGEN_HFADJ_HFADJ_GAIN_Gain_of_1_in_4 0x00400000 +#define AM_REG_CLKGEN_HFADJ_HFADJ_GAIN_Gain_of_1_in_8 0x00600000 +#define AM_REG_CLKGEN_HFADJ_HFADJ_GAIN_Gain_of_1_in_16 0x00800000 +#define AM_REG_CLKGEN_HFADJ_HFADJ_GAIN_Gain_of_1_in_32 0x00A00000 + +// XT warmup period for HFRC adjustment +#define AM_REG_CLKGEN_HFADJ_HFWARMUP_S 20 +#define AM_REG_CLKGEN_HFADJ_HFWARMUP_M 0x00100000 +#define AM_REG_CLKGEN_HFADJ_HFWARMUP(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_CLKGEN_HFADJ_HFWARMUP_1SEC 0x00000000 +#define AM_REG_CLKGEN_HFADJ_HFWARMUP_2SEC 0x00100000 + +// Target HFRC adjustment value. +#define AM_REG_CLKGEN_HFADJ_HFXTADJ_S 8 +#define AM_REG_CLKGEN_HFADJ_HFXTADJ_M 0x000FFF00 +#define AM_REG_CLKGEN_HFADJ_HFXTADJ(n) (((uint32_t)(n) << 8) & 0x000FFF00) + +// Repeat period for HFRC adjustment +#define AM_REG_CLKGEN_HFADJ_HFADJCK_S 1 +#define AM_REG_CLKGEN_HFADJ_HFADJCK_M 0x0000000E +#define AM_REG_CLKGEN_HFADJ_HFADJCK(n) (((uint32_t)(n) << 1) & 0x0000000E) +#define AM_REG_CLKGEN_HFADJ_HFADJCK_4SEC 0x00000000 +#define AM_REG_CLKGEN_HFADJ_HFADJCK_16SEC 0x00000002 +#define AM_REG_CLKGEN_HFADJ_HFADJCK_32SEC 0x00000004 +#define AM_REG_CLKGEN_HFADJ_HFADJCK_64SEC 0x00000006 +#define AM_REG_CLKGEN_HFADJ_HFADJCK_128SEC 0x00000008 +#define AM_REG_CLKGEN_HFADJ_HFADJCK_256SEC 0x0000000A +#define AM_REG_CLKGEN_HFADJ_HFADJCK_512SEC 0x0000000C +#define AM_REG_CLKGEN_HFADJ_HFADJCK_1024SEC 0x0000000E + +// HFRC adjustment control +#define AM_REG_CLKGEN_HFADJ_HFADJEN_S 0 +#define AM_REG_CLKGEN_HFADJ_HFADJEN_M 0x00000001 +#define AM_REG_CLKGEN_HFADJ_HFADJEN(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_CLKGEN_HFADJ_HFADJEN_DIS 0x00000000 +#define AM_REG_CLKGEN_HFADJ_HFADJEN_EN 0x00000001 + +//***************************************************************************** +// +// CLKGEN_HFVAL - HFADJ readback +// +//***************************************************************************** +// Current HFTUNE value +#define AM_REG_CLKGEN_HFVAL_HFTUNERB_S 0 +#define AM_REG_CLKGEN_HFVAL_HFTUNERB_M 0x000007FF +#define AM_REG_CLKGEN_HFVAL_HFTUNERB(n) (((uint32_t)(n) << 0) & 0x000007FF) + +//***************************************************************************** +// +// CLKGEN_CLOCKEN - Clock Enable Status +// +//***************************************************************************** +// Clock enable status +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_S 0 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_M 0xFFFFFFFF +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_ADC_CLKEN 0x00000001 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_CTIMER_CLKEN 0x00000002 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_CTIMER0A_CLKEN 0x00000004 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_CTIMER0B_CLKEN 0x00000008 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_CTIMER1A_CLKEN 0x00000010 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_CTIMER1B_CLKEN 0x00000020 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_CTIMER2A_CLKEN 0x00000040 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_CTIMER2B_CLKEN 0x00000080 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_CTIMER3A_CLKEN 0x00000100 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_CTIMER3B_CLKEN 0x00000200 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_IOMSTR0_CLKEN 0x00000400 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_IOMSTR1_CLKEN 0x00000800 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_IOMSTR2_CLKEN 0x00001000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_IOMSTR3_CLKEN 0x00002000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_IOMSTR4_CLKEN 0x00004000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_IOMSTR5_CLKEN 0x00008000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_IOMSTRIFC0_CLKEN 0x00010000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_IOMSTRIFC1_CLKEN 0x00020000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_IOMSTRIFC2_CLKEN 0x00040000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_IOMSTRIFC3_CLKEN 0x00080000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_IOMSTRIFC4_CLKEN 0x00100000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_IOMSTRIFC5_CLKEN 0x00200000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_IOSLAVE_CLKEN 0x00400000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_PDM_CLKEN 0x00800000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_PDMIFC_CLKEN 0x01000000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_RSTGEN_CLKEN 0x02000000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_SRAM_WIPE_CLKEN 0x04000000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_STIMER_CLKEN 0x08000000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_STIMER_CNT_CLKEN 0x10000000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_TPIU_CLKEN 0x20000000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_UART0_HCLK_CLKEN 0x40000000 +#define AM_REG_CLKGEN_CLOCKEN_CLOCKEN_UART0HF_CLKEN 0x80000000 + +//***************************************************************************** +// +// CLKGEN_CLOCKEN2 - Clock Enable Status +// +//***************************************************************************** +// Clock enable status 2 +#define AM_REG_CLKGEN_CLOCKEN2_CLOCKEN2_S 0 +#define AM_REG_CLKGEN_CLOCKEN2_CLOCKEN2_M 0xFFFFFFFF +#define AM_REG_CLKGEN_CLOCKEN2_CLOCKEN2(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) +#define AM_REG_CLKGEN_CLOCKEN2_CLOCKEN2_UART1_HCLK_CLKEN 0x00000001 +#define AM_REG_CLKGEN_CLOCKEN2_CLOCKEN2_UART1HF_CLKEN 0x00000002 +#define AM_REG_CLKGEN_CLOCKEN2_CLOCKEN2_WDT_CLKEN 0x00000004 +#define AM_REG_CLKGEN_CLOCKEN2_CLOCKEN2_XT_32KHz_EN 0x40000000 +#define AM_REG_CLKGEN_CLOCKEN2_CLOCKEN2_FRCHFRC 0x80000000 + +//***************************************************************************** +// +// CLKGEN_CLOCKEN3 - Clock Enable Status +// +//***************************************************************************** +// Clock enable status 3 +#define AM_REG_CLKGEN_CLOCKEN3_CLOCKEN3_S 0 +#define AM_REG_CLKGEN_CLOCKEN3_CLOCKEN3_M 0xFFFFFFFF +#define AM_REG_CLKGEN_CLOCKEN3_CLOCKEN3(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) +#define AM_REG_CLKGEN_CLOCKEN3_CLOCKEN3_periph_all_xtal_en 0x01000000 +#define AM_REG_CLKGEN_CLOCKEN3_CLOCKEN3_periph_all_hfrc_en 0x02000000 +#define AM_REG_CLKGEN_CLOCKEN3_CLOCKEN3_HFADJEN 0x04000000 +#define AM_REG_CLKGEN_CLOCKEN3_CLOCKEN3_HFRC_en_out 0x08000000 +#define AM_REG_CLKGEN_CLOCKEN3_CLOCKEN3_RTC_SOURCE 0x10000000 +#define AM_REG_CLKGEN_CLOCKEN3_CLOCKEN3_XTAL_EN 0x20000000 +#define AM_REG_CLKGEN_CLOCKEN3_CLOCKEN3_HFRC_EN 0x40000000 +#define AM_REG_CLKGEN_CLOCKEN3_CLOCKEN3_FLASHCLK_EN 0x80000000 + +//***************************************************************************** +// +// CLKGEN_UARTEN - UART Enable +// +//***************************************************************************** +// UART1 system clock control +#define AM_REG_CLKGEN_UARTEN_UART1EN_S 8 +#define AM_REG_CLKGEN_UARTEN_UART1EN_M 0x00000300 +#define AM_REG_CLKGEN_UARTEN_UART1EN(n) (((uint32_t)(n) << 8) & 0x00000300) +#define AM_REG_CLKGEN_UARTEN_UART1EN_DIS 0x00000000 +#define AM_REG_CLKGEN_UARTEN_UART1EN_EN 0x00000100 +#define AM_REG_CLKGEN_UARTEN_UART1EN_REDUCE_FREQ 0x00000200 +#define AM_REG_CLKGEN_UARTEN_UART1EN_EN_POWER_SAV 0x00000300 + +// UART0 system clock control +#define AM_REG_CLKGEN_UARTEN_UART0EN_S 0 +#define AM_REG_CLKGEN_UARTEN_UART0EN_M 0x00000003 +#define AM_REG_CLKGEN_UARTEN_UART0EN(n) (((uint32_t)(n) << 0) & 0x00000003) +#define AM_REG_CLKGEN_UARTEN_UART0EN_DIS 0x00000000 +#define AM_REG_CLKGEN_UARTEN_UART0EN_EN 0x00000001 +#define AM_REG_CLKGEN_UARTEN_UART0EN_REDUCE_FREQ 0x00000002 +#define AM_REG_CLKGEN_UARTEN_UART0EN_EN_POWER_SAV 0x00000003 + +#endif // AM_REG_CLKGEN_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_ctimer.h b/bsp/apollo2/libraries/drivers/regs/am_reg_ctimer.h new file mode 100644 index 0000000000..278849a74d --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_ctimer.h @@ -0,0 +1,1915 @@ +//***************************************************************************** +// +// am_reg_ctimer.h +//! @file +//! +//! @brief Register macros for the CTIMER module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_CTIMER_H +#define AM_REG_CTIMER_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_CTIMER_NUM_MODULES 1 +#define AM_REG_CTIMERn(n) \ + (REG_CTIMER_BASEADDR + 0x00000000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_CTIMER_TMR0_O 0x00000000 +#define AM_REG_CTIMER_CMPRA0_O 0x00000004 +#define AM_REG_CTIMER_CMPRB0_O 0x00000008 +#define AM_REG_CTIMER_CTRL0_O 0x0000000C +#define AM_REG_CTIMER_TMR1_O 0x00000010 +#define AM_REG_CTIMER_CMPRA1_O 0x00000014 +#define AM_REG_CTIMER_CMPRB1_O 0x00000018 +#define AM_REG_CTIMER_CTRL1_O 0x0000001C +#define AM_REG_CTIMER_TMR2_O 0x00000020 +#define AM_REG_CTIMER_CMPRA2_O 0x00000024 +#define AM_REG_CTIMER_CMPRB2_O 0x00000028 +#define AM_REG_CTIMER_CTRL2_O 0x0000002C +#define AM_REG_CTIMER_TMR3_O 0x00000030 +#define AM_REG_CTIMER_CMPRA3_O 0x00000034 +#define AM_REG_CTIMER_CMPRB3_O 0x00000038 +#define AM_REG_CTIMER_CTRL3_O 0x0000003C +#define AM_REG_CTIMER_STCFG_O 0x00000100 +#define AM_REG_CTIMER_STTMR_O 0x00000104 +#define AM_REG_CTIMER_CAPTURE_CONTROL_O 0x00000108 +#define AM_REG_CTIMER_SCMPR0_O 0x00000110 +#define AM_REG_CTIMER_SCMPR1_O 0x00000114 +#define AM_REG_CTIMER_SCMPR2_O 0x00000118 +#define AM_REG_CTIMER_SCMPR3_O 0x0000011C +#define AM_REG_CTIMER_SCMPR4_O 0x00000120 +#define AM_REG_CTIMER_SCMPR5_O 0x00000124 +#define AM_REG_CTIMER_SCMPR6_O 0x00000128 +#define AM_REG_CTIMER_SCMPR7_O 0x0000012C +#define AM_REG_CTIMER_SCAPT0_O 0x000001E0 +#define AM_REG_CTIMER_SCAPT1_O 0x000001E4 +#define AM_REG_CTIMER_SCAPT2_O 0x000001E8 +#define AM_REG_CTIMER_SCAPT3_O 0x000001EC +#define AM_REG_CTIMER_SNVR0_O 0x000001F0 +#define AM_REG_CTIMER_SNVR1_O 0x000001F4 +#define AM_REG_CTIMER_SNVR2_O 0x000001F8 +#define AM_REG_CTIMER_INTEN_O 0x00000200 +#define AM_REG_CTIMER_INTSTAT_O 0x00000204 +#define AM_REG_CTIMER_INTCLR_O 0x00000208 +#define AM_REG_CTIMER_INTSET_O 0x0000020C +#define AM_REG_CTIMER_STMINTEN_O 0x00000300 +#define AM_REG_CTIMER_STMINTSTAT_O 0x00000304 +#define AM_REG_CTIMER_STMINTCLR_O 0x00000308 +#define AM_REG_CTIMER_STMINTSET_O 0x0000030C + +//***************************************************************************** +// +// CTIMER_INTEN - Counter/Timer Interrupts: Enable +// +//***************************************************************************** +// Counter/Timer B3 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTEN_CTMRB3C1INT_S 15 +#define AM_REG_CTIMER_INTEN_CTMRB3C1INT_M 0x00008000 +#define AM_REG_CTIMER_INTEN_CTMRB3C1INT(n) (((uint32_t)(n) << 15) & 0x00008000) + +// Counter/Timer A3 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTEN_CTMRA3C1INT_S 14 +#define AM_REG_CTIMER_INTEN_CTMRA3C1INT_M 0x00004000 +#define AM_REG_CTIMER_INTEN_CTMRA3C1INT(n) (((uint32_t)(n) << 14) & 0x00004000) + +// Counter/Timer B2 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTEN_CTMRB2C1INT_S 13 +#define AM_REG_CTIMER_INTEN_CTMRB2C1INT_M 0x00002000 +#define AM_REG_CTIMER_INTEN_CTMRB2C1INT(n) (((uint32_t)(n) << 13) & 0x00002000) + +// Counter/Timer A2 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTEN_CTMRA2C1INT_S 12 +#define AM_REG_CTIMER_INTEN_CTMRA2C1INT_M 0x00001000 +#define AM_REG_CTIMER_INTEN_CTMRA2C1INT(n) (((uint32_t)(n) << 12) & 0x00001000) + +// Counter/Timer B1 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTEN_CTMRB1C1INT_S 11 +#define AM_REG_CTIMER_INTEN_CTMRB1C1INT_M 0x00000800 +#define AM_REG_CTIMER_INTEN_CTMRB1C1INT(n) (((uint32_t)(n) << 11) & 0x00000800) + +// Counter/Timer A1 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTEN_CTMRA1C1INT_S 10 +#define AM_REG_CTIMER_INTEN_CTMRA1C1INT_M 0x00000400 +#define AM_REG_CTIMER_INTEN_CTMRA1C1INT(n) (((uint32_t)(n) << 10) & 0x00000400) + +// Counter/Timer B0 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTEN_CTMRB0C1INT_S 9 +#define AM_REG_CTIMER_INTEN_CTMRB0C1INT_M 0x00000200 +#define AM_REG_CTIMER_INTEN_CTMRB0C1INT(n) (((uint32_t)(n) << 9) & 0x00000200) + +// Counter/Timer A0 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTEN_CTMRA0C1INT_S 8 +#define AM_REG_CTIMER_INTEN_CTMRA0C1INT_M 0x00000100 +#define AM_REG_CTIMER_INTEN_CTMRA0C1INT(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Counter/Timer B3 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTEN_CTMRB3C0INT_S 7 +#define AM_REG_CTIMER_INTEN_CTMRB3C0INT_M 0x00000080 +#define AM_REG_CTIMER_INTEN_CTMRB3C0INT(n) (((uint32_t)(n) << 7) & 0x00000080) + +// Counter/Timer A3 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTEN_CTMRA3C0INT_S 6 +#define AM_REG_CTIMER_INTEN_CTMRA3C0INT_M 0x00000040 +#define AM_REG_CTIMER_INTEN_CTMRA3C0INT(n) (((uint32_t)(n) << 6) & 0x00000040) + +// Counter/Timer B2 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTEN_CTMRB2C0INT_S 5 +#define AM_REG_CTIMER_INTEN_CTMRB2C0INT_M 0x00000020 +#define AM_REG_CTIMER_INTEN_CTMRB2C0INT(n) (((uint32_t)(n) << 5) & 0x00000020) + +// Counter/Timer A2 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTEN_CTMRA2C0INT_S 4 +#define AM_REG_CTIMER_INTEN_CTMRA2C0INT_M 0x00000010 +#define AM_REG_CTIMER_INTEN_CTMRA2C0INT(n) (((uint32_t)(n) << 4) & 0x00000010) + +// Counter/Timer B1 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTEN_CTMRB1C0INT_S 3 +#define AM_REG_CTIMER_INTEN_CTMRB1C0INT_M 0x00000008 +#define AM_REG_CTIMER_INTEN_CTMRB1C0INT(n) (((uint32_t)(n) << 3) & 0x00000008) + +// Counter/Timer A1 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTEN_CTMRA1C0INT_S 2 +#define AM_REG_CTIMER_INTEN_CTMRA1C0INT_M 0x00000004 +#define AM_REG_CTIMER_INTEN_CTMRA1C0INT(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Counter/Timer B0 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTEN_CTMRB0C0INT_S 1 +#define AM_REG_CTIMER_INTEN_CTMRB0C0INT_M 0x00000002 +#define AM_REG_CTIMER_INTEN_CTMRB0C0INT(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Counter/Timer A0 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTEN_CTMRA0C0INT_S 0 +#define AM_REG_CTIMER_INTEN_CTMRA0C0INT_M 0x00000001 +#define AM_REG_CTIMER_INTEN_CTMRA0C0INT(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// CTIMER_INTSTAT - Counter/Timer Interrupts: Status +// +//***************************************************************************** +// Counter/Timer B3 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTSTAT_CTMRB3C1INT_S 15 +#define AM_REG_CTIMER_INTSTAT_CTMRB3C1INT_M 0x00008000 +#define AM_REG_CTIMER_INTSTAT_CTMRB3C1INT(n) (((uint32_t)(n) << 15) & 0x00008000) + +// Counter/Timer A3 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTSTAT_CTMRA3C1INT_S 14 +#define AM_REG_CTIMER_INTSTAT_CTMRA3C1INT_M 0x00004000 +#define AM_REG_CTIMER_INTSTAT_CTMRA3C1INT(n) (((uint32_t)(n) << 14) & 0x00004000) + +// Counter/Timer B2 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTSTAT_CTMRB2C1INT_S 13 +#define AM_REG_CTIMER_INTSTAT_CTMRB2C1INT_M 0x00002000 +#define AM_REG_CTIMER_INTSTAT_CTMRB2C1INT(n) (((uint32_t)(n) << 13) & 0x00002000) + +// Counter/Timer A2 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTSTAT_CTMRA2C1INT_S 12 +#define AM_REG_CTIMER_INTSTAT_CTMRA2C1INT_M 0x00001000 +#define AM_REG_CTIMER_INTSTAT_CTMRA2C1INT(n) (((uint32_t)(n) << 12) & 0x00001000) + +// Counter/Timer B1 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTSTAT_CTMRB1C1INT_S 11 +#define AM_REG_CTIMER_INTSTAT_CTMRB1C1INT_M 0x00000800 +#define AM_REG_CTIMER_INTSTAT_CTMRB1C1INT(n) (((uint32_t)(n) << 11) & 0x00000800) + +// Counter/Timer A1 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTSTAT_CTMRA1C1INT_S 10 +#define AM_REG_CTIMER_INTSTAT_CTMRA1C1INT_M 0x00000400 +#define AM_REG_CTIMER_INTSTAT_CTMRA1C1INT(n) (((uint32_t)(n) << 10) & 0x00000400) + +// Counter/Timer B0 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTSTAT_CTMRB0C1INT_S 9 +#define AM_REG_CTIMER_INTSTAT_CTMRB0C1INT_M 0x00000200 +#define AM_REG_CTIMER_INTSTAT_CTMRB0C1INT(n) (((uint32_t)(n) << 9) & 0x00000200) + +// Counter/Timer A0 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTSTAT_CTMRA0C1INT_S 8 +#define AM_REG_CTIMER_INTSTAT_CTMRA0C1INT_M 0x00000100 +#define AM_REG_CTIMER_INTSTAT_CTMRA0C1INT(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Counter/Timer B3 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTSTAT_CTMRB3C0INT_S 7 +#define AM_REG_CTIMER_INTSTAT_CTMRB3C0INT_M 0x00000080 +#define AM_REG_CTIMER_INTSTAT_CTMRB3C0INT(n) (((uint32_t)(n) << 7) & 0x00000080) + +// Counter/Timer A3 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTSTAT_CTMRA3C0INT_S 6 +#define AM_REG_CTIMER_INTSTAT_CTMRA3C0INT_M 0x00000040 +#define AM_REG_CTIMER_INTSTAT_CTMRA3C0INT(n) (((uint32_t)(n) << 6) & 0x00000040) + +// Counter/Timer B2 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTSTAT_CTMRB2C0INT_S 5 +#define AM_REG_CTIMER_INTSTAT_CTMRB2C0INT_M 0x00000020 +#define AM_REG_CTIMER_INTSTAT_CTMRB2C0INT(n) (((uint32_t)(n) << 5) & 0x00000020) + +// Counter/Timer A2 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTSTAT_CTMRA2C0INT_S 4 +#define AM_REG_CTIMER_INTSTAT_CTMRA2C0INT_M 0x00000010 +#define AM_REG_CTIMER_INTSTAT_CTMRA2C0INT(n) (((uint32_t)(n) << 4) & 0x00000010) + +// Counter/Timer B1 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTSTAT_CTMRB1C0INT_S 3 +#define AM_REG_CTIMER_INTSTAT_CTMRB1C0INT_M 0x00000008 +#define AM_REG_CTIMER_INTSTAT_CTMRB1C0INT(n) (((uint32_t)(n) << 3) & 0x00000008) + +// Counter/Timer A1 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTSTAT_CTMRA1C0INT_S 2 +#define AM_REG_CTIMER_INTSTAT_CTMRA1C0INT_M 0x00000004 +#define AM_REG_CTIMER_INTSTAT_CTMRA1C0INT(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Counter/Timer B0 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTSTAT_CTMRB0C0INT_S 1 +#define AM_REG_CTIMER_INTSTAT_CTMRB0C0INT_M 0x00000002 +#define AM_REG_CTIMER_INTSTAT_CTMRB0C0INT(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Counter/Timer A0 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTSTAT_CTMRA0C0INT_S 0 +#define AM_REG_CTIMER_INTSTAT_CTMRA0C0INT_M 0x00000001 +#define AM_REG_CTIMER_INTSTAT_CTMRA0C0INT(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// CTIMER_INTCLR - Counter/Timer Interrupts: Clear +// +//***************************************************************************** +// Counter/Timer B3 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTCLR_CTMRB3C1INT_S 15 +#define AM_REG_CTIMER_INTCLR_CTMRB3C1INT_M 0x00008000 +#define AM_REG_CTIMER_INTCLR_CTMRB3C1INT(n) (((uint32_t)(n) << 15) & 0x00008000) + +// Counter/Timer A3 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTCLR_CTMRA3C1INT_S 14 +#define AM_REG_CTIMER_INTCLR_CTMRA3C1INT_M 0x00004000 +#define AM_REG_CTIMER_INTCLR_CTMRA3C1INT(n) (((uint32_t)(n) << 14) & 0x00004000) + +// Counter/Timer B2 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTCLR_CTMRB2C1INT_S 13 +#define AM_REG_CTIMER_INTCLR_CTMRB2C1INT_M 0x00002000 +#define AM_REG_CTIMER_INTCLR_CTMRB2C1INT(n) (((uint32_t)(n) << 13) & 0x00002000) + +// Counter/Timer A2 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTCLR_CTMRA2C1INT_S 12 +#define AM_REG_CTIMER_INTCLR_CTMRA2C1INT_M 0x00001000 +#define AM_REG_CTIMER_INTCLR_CTMRA2C1INT(n) (((uint32_t)(n) << 12) & 0x00001000) + +// Counter/Timer B1 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTCLR_CTMRB1C1INT_S 11 +#define AM_REG_CTIMER_INTCLR_CTMRB1C1INT_M 0x00000800 +#define AM_REG_CTIMER_INTCLR_CTMRB1C1INT(n) (((uint32_t)(n) << 11) & 0x00000800) + +// Counter/Timer A1 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTCLR_CTMRA1C1INT_S 10 +#define AM_REG_CTIMER_INTCLR_CTMRA1C1INT_M 0x00000400 +#define AM_REG_CTIMER_INTCLR_CTMRA1C1INT(n) (((uint32_t)(n) << 10) & 0x00000400) + +// Counter/Timer B0 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTCLR_CTMRB0C1INT_S 9 +#define AM_REG_CTIMER_INTCLR_CTMRB0C1INT_M 0x00000200 +#define AM_REG_CTIMER_INTCLR_CTMRB0C1INT(n) (((uint32_t)(n) << 9) & 0x00000200) + +// Counter/Timer A0 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTCLR_CTMRA0C1INT_S 8 +#define AM_REG_CTIMER_INTCLR_CTMRA0C1INT_M 0x00000100 +#define AM_REG_CTIMER_INTCLR_CTMRA0C1INT(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Counter/Timer B3 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTCLR_CTMRB3C0INT_S 7 +#define AM_REG_CTIMER_INTCLR_CTMRB3C0INT_M 0x00000080 +#define AM_REG_CTIMER_INTCLR_CTMRB3C0INT(n) (((uint32_t)(n) << 7) & 0x00000080) + +// Counter/Timer A3 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTCLR_CTMRA3C0INT_S 6 +#define AM_REG_CTIMER_INTCLR_CTMRA3C0INT_M 0x00000040 +#define AM_REG_CTIMER_INTCLR_CTMRA3C0INT(n) (((uint32_t)(n) << 6) & 0x00000040) + +// Counter/Timer B2 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTCLR_CTMRB2C0INT_S 5 +#define AM_REG_CTIMER_INTCLR_CTMRB2C0INT_M 0x00000020 +#define AM_REG_CTIMER_INTCLR_CTMRB2C0INT(n) (((uint32_t)(n) << 5) & 0x00000020) + +// Counter/Timer A2 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTCLR_CTMRA2C0INT_S 4 +#define AM_REG_CTIMER_INTCLR_CTMRA2C0INT_M 0x00000010 +#define AM_REG_CTIMER_INTCLR_CTMRA2C0INT(n) (((uint32_t)(n) << 4) & 0x00000010) + +// Counter/Timer B1 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTCLR_CTMRB1C0INT_S 3 +#define AM_REG_CTIMER_INTCLR_CTMRB1C0INT_M 0x00000008 +#define AM_REG_CTIMER_INTCLR_CTMRB1C0INT(n) (((uint32_t)(n) << 3) & 0x00000008) + +// Counter/Timer A1 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTCLR_CTMRA1C0INT_S 2 +#define AM_REG_CTIMER_INTCLR_CTMRA1C0INT_M 0x00000004 +#define AM_REG_CTIMER_INTCLR_CTMRA1C0INT(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Counter/Timer B0 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTCLR_CTMRB0C0INT_S 1 +#define AM_REG_CTIMER_INTCLR_CTMRB0C0INT_M 0x00000002 +#define AM_REG_CTIMER_INTCLR_CTMRB0C0INT(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Counter/Timer A0 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTCLR_CTMRA0C0INT_S 0 +#define AM_REG_CTIMER_INTCLR_CTMRA0C0INT_M 0x00000001 +#define AM_REG_CTIMER_INTCLR_CTMRA0C0INT(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// CTIMER_INTSET - Counter/Timer Interrupts: Set +// +//***************************************************************************** +// Counter/Timer B3 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTSET_CTMRB3C1INT_S 15 +#define AM_REG_CTIMER_INTSET_CTMRB3C1INT_M 0x00008000 +#define AM_REG_CTIMER_INTSET_CTMRB3C1INT(n) (((uint32_t)(n) << 15) & 0x00008000) + +// Counter/Timer A3 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTSET_CTMRA3C1INT_S 14 +#define AM_REG_CTIMER_INTSET_CTMRA3C1INT_M 0x00004000 +#define AM_REG_CTIMER_INTSET_CTMRA3C1INT(n) (((uint32_t)(n) << 14) & 0x00004000) + +// Counter/Timer B2 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTSET_CTMRB2C1INT_S 13 +#define AM_REG_CTIMER_INTSET_CTMRB2C1INT_M 0x00002000 +#define AM_REG_CTIMER_INTSET_CTMRB2C1INT(n) (((uint32_t)(n) << 13) & 0x00002000) + +// Counter/Timer A2 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTSET_CTMRA2C1INT_S 12 +#define AM_REG_CTIMER_INTSET_CTMRA2C1INT_M 0x00001000 +#define AM_REG_CTIMER_INTSET_CTMRA2C1INT(n) (((uint32_t)(n) << 12) & 0x00001000) + +// Counter/Timer B1 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTSET_CTMRB1C1INT_S 11 +#define AM_REG_CTIMER_INTSET_CTMRB1C1INT_M 0x00000800 +#define AM_REG_CTIMER_INTSET_CTMRB1C1INT(n) (((uint32_t)(n) << 11) & 0x00000800) + +// Counter/Timer A1 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTSET_CTMRA1C1INT_S 10 +#define AM_REG_CTIMER_INTSET_CTMRA1C1INT_M 0x00000400 +#define AM_REG_CTIMER_INTSET_CTMRA1C1INT(n) (((uint32_t)(n) << 10) & 0x00000400) + +// Counter/Timer B0 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTSET_CTMRB0C1INT_S 9 +#define AM_REG_CTIMER_INTSET_CTMRB0C1INT_M 0x00000200 +#define AM_REG_CTIMER_INTSET_CTMRB0C1INT(n) (((uint32_t)(n) << 9) & 0x00000200) + +// Counter/Timer A0 interrupt based on COMPR1. +#define AM_REG_CTIMER_INTSET_CTMRA0C1INT_S 8 +#define AM_REG_CTIMER_INTSET_CTMRA0C1INT_M 0x00000100 +#define AM_REG_CTIMER_INTSET_CTMRA0C1INT(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Counter/Timer B3 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTSET_CTMRB3C0INT_S 7 +#define AM_REG_CTIMER_INTSET_CTMRB3C0INT_M 0x00000080 +#define AM_REG_CTIMER_INTSET_CTMRB3C0INT(n) (((uint32_t)(n) << 7) & 0x00000080) + +// Counter/Timer A3 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTSET_CTMRA3C0INT_S 6 +#define AM_REG_CTIMER_INTSET_CTMRA3C0INT_M 0x00000040 +#define AM_REG_CTIMER_INTSET_CTMRA3C0INT(n) (((uint32_t)(n) << 6) & 0x00000040) + +// Counter/Timer B2 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTSET_CTMRB2C0INT_S 5 +#define AM_REG_CTIMER_INTSET_CTMRB2C0INT_M 0x00000020 +#define AM_REG_CTIMER_INTSET_CTMRB2C0INT(n) (((uint32_t)(n) << 5) & 0x00000020) + +// Counter/Timer A2 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTSET_CTMRA2C0INT_S 4 +#define AM_REG_CTIMER_INTSET_CTMRA2C0INT_M 0x00000010 +#define AM_REG_CTIMER_INTSET_CTMRA2C0INT(n) (((uint32_t)(n) << 4) & 0x00000010) + +// Counter/Timer B1 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTSET_CTMRB1C0INT_S 3 +#define AM_REG_CTIMER_INTSET_CTMRB1C0INT_M 0x00000008 +#define AM_REG_CTIMER_INTSET_CTMRB1C0INT(n) (((uint32_t)(n) << 3) & 0x00000008) + +// Counter/Timer A1 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTSET_CTMRA1C0INT_S 2 +#define AM_REG_CTIMER_INTSET_CTMRA1C0INT_M 0x00000004 +#define AM_REG_CTIMER_INTSET_CTMRA1C0INT(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Counter/Timer B0 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTSET_CTMRB0C0INT_S 1 +#define AM_REG_CTIMER_INTSET_CTMRB0C0INT_M 0x00000002 +#define AM_REG_CTIMER_INTSET_CTMRB0C0INT(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Counter/Timer A0 interrupt based on COMPR0. +#define AM_REG_CTIMER_INTSET_CTMRA0C0INT_S 0 +#define AM_REG_CTIMER_INTSET_CTMRA0C0INT_M 0x00000001 +#define AM_REG_CTIMER_INTSET_CTMRA0C0INT(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// CTIMER_STMINTEN - STIMER Interrupt registers: Enable +// +//***************************************************************************** +// CAPTURE register D has grabbed the value in the counter +#define AM_REG_CTIMER_STMINTEN_CAPTURED_S 12 +#define AM_REG_CTIMER_STMINTEN_CAPTURED_M 0x00001000 +#define AM_REG_CTIMER_STMINTEN_CAPTURED(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_CTIMER_STMINTEN_CAPTURED_CAPD_INT 0x00001000 + +// CAPTURE register C has grabbed the value in the counter +#define AM_REG_CTIMER_STMINTEN_CAPTUREC_S 11 +#define AM_REG_CTIMER_STMINTEN_CAPTUREC_M 0x00000800 +#define AM_REG_CTIMER_STMINTEN_CAPTUREC(n) (((uint32_t)(n) << 11) & 0x00000800) +#define AM_REG_CTIMER_STMINTEN_CAPTUREC_CAPC_INT 0x00000800 + +// CAPTURE register B has grabbed the value in the counter +#define AM_REG_CTIMER_STMINTEN_CAPTUREB_S 10 +#define AM_REG_CTIMER_STMINTEN_CAPTUREB_M 0x00000400 +#define AM_REG_CTIMER_STMINTEN_CAPTUREB(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_CTIMER_STMINTEN_CAPTUREB_CAPB_INT 0x00000400 + +// CAPTURE register A has grabbed the value in the counter +#define AM_REG_CTIMER_STMINTEN_CAPTUREA_S 9 +#define AM_REG_CTIMER_STMINTEN_CAPTUREA_M 0x00000200 +#define AM_REG_CTIMER_STMINTEN_CAPTUREA(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_CTIMER_STMINTEN_CAPTUREA_CAPA_INT 0x00000200 + +// COUNTER over flowed from 0xFFFFFFFF back to 0x00000000. +#define AM_REG_CTIMER_STMINTEN_OVERFLOW_S 8 +#define AM_REG_CTIMER_STMINTEN_OVERFLOW_M 0x00000100 +#define AM_REG_CTIMER_STMINTEN_OVERFLOW(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_CTIMER_STMINTEN_OVERFLOW_OFLOW_INT 0x00000100 + +// COUNTER is greater than or equal to COMPARE register H. +#define AM_REG_CTIMER_STMINTEN_COMPAREH_S 7 +#define AM_REG_CTIMER_STMINTEN_COMPAREH_M 0x00000080 +#define AM_REG_CTIMER_STMINTEN_COMPAREH(n) (((uint32_t)(n) << 7) & 0x00000080) +#define AM_REG_CTIMER_STMINTEN_COMPAREH_COMPARED 0x00000080 + +// COUNTER is greater than or equal to COMPARE register G. +#define AM_REG_CTIMER_STMINTEN_COMPAREG_S 6 +#define AM_REG_CTIMER_STMINTEN_COMPAREG_M 0x00000040 +#define AM_REG_CTIMER_STMINTEN_COMPAREG(n) (((uint32_t)(n) << 6) & 0x00000040) +#define AM_REG_CTIMER_STMINTEN_COMPAREG_COMPARED 0x00000040 + +// COUNTER is greater than or equal to COMPARE register F. +#define AM_REG_CTIMER_STMINTEN_COMPAREF_S 5 +#define AM_REG_CTIMER_STMINTEN_COMPAREF_M 0x00000020 +#define AM_REG_CTIMER_STMINTEN_COMPAREF(n) (((uint32_t)(n) << 5) & 0x00000020) +#define AM_REG_CTIMER_STMINTEN_COMPAREF_COMPARED 0x00000020 + +// COUNTER is greater than or equal to COMPARE register E. +#define AM_REG_CTIMER_STMINTEN_COMPAREE_S 4 +#define AM_REG_CTIMER_STMINTEN_COMPAREE_M 0x00000010 +#define AM_REG_CTIMER_STMINTEN_COMPAREE(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_CTIMER_STMINTEN_COMPAREE_COMPARED 0x00000010 + +// COUNTER is greater than or equal to COMPARE register D. +#define AM_REG_CTIMER_STMINTEN_COMPARED_S 3 +#define AM_REG_CTIMER_STMINTEN_COMPARED_M 0x00000008 +#define AM_REG_CTIMER_STMINTEN_COMPARED(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_CTIMER_STMINTEN_COMPARED_COMPARED 0x00000008 + +// COUNTER is greater than or equal to COMPARE register C. +#define AM_REG_CTIMER_STMINTEN_COMPAREC_S 2 +#define AM_REG_CTIMER_STMINTEN_COMPAREC_M 0x00000004 +#define AM_REG_CTIMER_STMINTEN_COMPAREC(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_CTIMER_STMINTEN_COMPAREC_COMPARED 0x00000004 + +// COUNTER is greater than or equal to COMPARE register B. +#define AM_REG_CTIMER_STMINTEN_COMPAREB_S 1 +#define AM_REG_CTIMER_STMINTEN_COMPAREB_M 0x00000002 +#define AM_REG_CTIMER_STMINTEN_COMPAREB(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_CTIMER_STMINTEN_COMPAREB_COMPARED 0x00000002 + +// COUNTER is greater than or equal to COMPARE register A. +#define AM_REG_CTIMER_STMINTEN_COMPAREA_S 0 +#define AM_REG_CTIMER_STMINTEN_COMPAREA_M 0x00000001 +#define AM_REG_CTIMER_STMINTEN_COMPAREA(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_CTIMER_STMINTEN_COMPAREA_COMPARED 0x00000001 + +//***************************************************************************** +// +// CTIMER_STMINTSTAT - STIMER Interrupt registers: Status +// +//***************************************************************************** +// CAPTURE register D has grabbed the value in the counter +#define AM_REG_CTIMER_STMINTSTAT_CAPTURED_S 12 +#define AM_REG_CTIMER_STMINTSTAT_CAPTURED_M 0x00001000 +#define AM_REG_CTIMER_STMINTSTAT_CAPTURED(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_CTIMER_STMINTSTAT_CAPTURED_CAPD_INT 0x00001000 + +// CAPTURE register C has grabbed the value in the counter +#define AM_REG_CTIMER_STMINTSTAT_CAPTUREC_S 11 +#define AM_REG_CTIMER_STMINTSTAT_CAPTUREC_M 0x00000800 +#define AM_REG_CTIMER_STMINTSTAT_CAPTUREC(n) (((uint32_t)(n) << 11) & 0x00000800) +#define AM_REG_CTIMER_STMINTSTAT_CAPTUREC_CAPC_INT 0x00000800 + +// CAPTURE register B has grabbed the value in the counter +#define AM_REG_CTIMER_STMINTSTAT_CAPTUREB_S 10 +#define AM_REG_CTIMER_STMINTSTAT_CAPTUREB_M 0x00000400 +#define AM_REG_CTIMER_STMINTSTAT_CAPTUREB(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_CTIMER_STMINTSTAT_CAPTUREB_CAPB_INT 0x00000400 + +// CAPTURE register A has grabbed the value in the counter +#define AM_REG_CTIMER_STMINTSTAT_CAPTUREA_S 9 +#define AM_REG_CTIMER_STMINTSTAT_CAPTUREA_M 0x00000200 +#define AM_REG_CTIMER_STMINTSTAT_CAPTUREA(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_CTIMER_STMINTSTAT_CAPTUREA_CAPA_INT 0x00000200 + +// COUNTER over flowed from 0xFFFFFFFF back to 0x00000000. +#define AM_REG_CTIMER_STMINTSTAT_OVERFLOW_S 8 +#define AM_REG_CTIMER_STMINTSTAT_OVERFLOW_M 0x00000100 +#define AM_REG_CTIMER_STMINTSTAT_OVERFLOW(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_CTIMER_STMINTSTAT_OVERFLOW_OFLOW_INT 0x00000100 + +// COUNTER is greater than or equal to COMPARE register H. +#define AM_REG_CTIMER_STMINTSTAT_COMPAREH_S 7 +#define AM_REG_CTIMER_STMINTSTAT_COMPAREH_M 0x00000080 +#define AM_REG_CTIMER_STMINTSTAT_COMPAREH(n) (((uint32_t)(n) << 7) & 0x00000080) +#define AM_REG_CTIMER_STMINTSTAT_COMPAREH_COMPARED 0x00000080 + +// COUNTER is greater than or equal to COMPARE register G. +#define AM_REG_CTIMER_STMINTSTAT_COMPAREG_S 6 +#define AM_REG_CTIMER_STMINTSTAT_COMPAREG_M 0x00000040 +#define AM_REG_CTIMER_STMINTSTAT_COMPAREG(n) (((uint32_t)(n) << 6) & 0x00000040) +#define AM_REG_CTIMER_STMINTSTAT_COMPAREG_COMPARED 0x00000040 + +// COUNTER is greater than or equal to COMPARE register F. +#define AM_REG_CTIMER_STMINTSTAT_COMPAREF_S 5 +#define AM_REG_CTIMER_STMINTSTAT_COMPAREF_M 0x00000020 +#define AM_REG_CTIMER_STMINTSTAT_COMPAREF(n) (((uint32_t)(n) << 5) & 0x00000020) +#define AM_REG_CTIMER_STMINTSTAT_COMPAREF_COMPARED 0x00000020 + +// COUNTER is greater than or equal to COMPARE register E. +#define AM_REG_CTIMER_STMINTSTAT_COMPAREE_S 4 +#define AM_REG_CTIMER_STMINTSTAT_COMPAREE_M 0x00000010 +#define AM_REG_CTIMER_STMINTSTAT_COMPAREE(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_CTIMER_STMINTSTAT_COMPAREE_COMPARED 0x00000010 + +// COUNTER is greater than or equal to COMPARE register D. +#define AM_REG_CTIMER_STMINTSTAT_COMPARED_S 3 +#define AM_REG_CTIMER_STMINTSTAT_COMPARED_M 0x00000008 +#define AM_REG_CTIMER_STMINTSTAT_COMPARED(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_CTIMER_STMINTSTAT_COMPARED_COMPARED 0x00000008 + +// COUNTER is greater than or equal to COMPARE register C. +#define AM_REG_CTIMER_STMINTSTAT_COMPAREC_S 2 +#define AM_REG_CTIMER_STMINTSTAT_COMPAREC_M 0x00000004 +#define AM_REG_CTIMER_STMINTSTAT_COMPAREC(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_CTIMER_STMINTSTAT_COMPAREC_COMPARED 0x00000004 + +// COUNTER is greater than or equal to COMPARE register B. +#define AM_REG_CTIMER_STMINTSTAT_COMPAREB_S 1 +#define AM_REG_CTIMER_STMINTSTAT_COMPAREB_M 0x00000002 +#define AM_REG_CTIMER_STMINTSTAT_COMPAREB(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_CTIMER_STMINTSTAT_COMPAREB_COMPARED 0x00000002 + +// COUNTER is greater than or equal to COMPARE register A. +#define AM_REG_CTIMER_STMINTSTAT_COMPAREA_S 0 +#define AM_REG_CTIMER_STMINTSTAT_COMPAREA_M 0x00000001 +#define AM_REG_CTIMER_STMINTSTAT_COMPAREA(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_CTIMER_STMINTSTAT_COMPAREA_COMPARED 0x00000001 + +//***************************************************************************** +// +// CTIMER_STMINTCLR - STIMER Interrupt registers: Clear +// +//***************************************************************************** +// CAPTURE register D has grabbed the value in the counter +#define AM_REG_CTIMER_STMINTCLR_CAPTURED_S 12 +#define AM_REG_CTIMER_STMINTCLR_CAPTURED_M 0x00001000 +#define AM_REG_CTIMER_STMINTCLR_CAPTURED(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_CTIMER_STMINTCLR_CAPTURED_CAPD_INT 0x00001000 + +// CAPTURE register C has grabbed the value in the counter +#define AM_REG_CTIMER_STMINTCLR_CAPTUREC_S 11 +#define AM_REG_CTIMER_STMINTCLR_CAPTUREC_M 0x00000800 +#define AM_REG_CTIMER_STMINTCLR_CAPTUREC(n) (((uint32_t)(n) << 11) & 0x00000800) +#define AM_REG_CTIMER_STMINTCLR_CAPTUREC_CAPC_INT 0x00000800 + +// CAPTURE register B has grabbed the value in the counter +#define AM_REG_CTIMER_STMINTCLR_CAPTUREB_S 10 +#define AM_REG_CTIMER_STMINTCLR_CAPTUREB_M 0x00000400 +#define AM_REG_CTIMER_STMINTCLR_CAPTUREB(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_CTIMER_STMINTCLR_CAPTUREB_CAPB_INT 0x00000400 + +// CAPTURE register A has grabbed the value in the counter +#define AM_REG_CTIMER_STMINTCLR_CAPTUREA_S 9 +#define AM_REG_CTIMER_STMINTCLR_CAPTUREA_M 0x00000200 +#define AM_REG_CTIMER_STMINTCLR_CAPTUREA(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_CTIMER_STMINTCLR_CAPTUREA_CAPA_INT 0x00000200 + +// COUNTER over flowed from 0xFFFFFFFF back to 0x00000000. +#define AM_REG_CTIMER_STMINTCLR_OVERFLOW_S 8 +#define AM_REG_CTIMER_STMINTCLR_OVERFLOW_M 0x00000100 +#define AM_REG_CTIMER_STMINTCLR_OVERFLOW(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_CTIMER_STMINTCLR_OVERFLOW_OFLOW_INT 0x00000100 + +// COUNTER is greater than or equal to COMPARE register H. +#define AM_REG_CTIMER_STMINTCLR_COMPAREH_S 7 +#define AM_REG_CTIMER_STMINTCLR_COMPAREH_M 0x00000080 +#define AM_REG_CTIMER_STMINTCLR_COMPAREH(n) (((uint32_t)(n) << 7) & 0x00000080) +#define AM_REG_CTIMER_STMINTCLR_COMPAREH_COMPARED 0x00000080 + +// COUNTER is greater than or equal to COMPARE register G. +#define AM_REG_CTIMER_STMINTCLR_COMPAREG_S 6 +#define AM_REG_CTIMER_STMINTCLR_COMPAREG_M 0x00000040 +#define AM_REG_CTIMER_STMINTCLR_COMPAREG(n) (((uint32_t)(n) << 6) & 0x00000040) +#define AM_REG_CTIMER_STMINTCLR_COMPAREG_COMPARED 0x00000040 + +// COUNTER is greater than or equal to COMPARE register F. +#define AM_REG_CTIMER_STMINTCLR_COMPAREF_S 5 +#define AM_REG_CTIMER_STMINTCLR_COMPAREF_M 0x00000020 +#define AM_REG_CTIMER_STMINTCLR_COMPAREF(n) (((uint32_t)(n) << 5) & 0x00000020) +#define AM_REG_CTIMER_STMINTCLR_COMPAREF_COMPARED 0x00000020 + +// COUNTER is greater than or equal to COMPARE register E. +#define AM_REG_CTIMER_STMINTCLR_COMPAREE_S 4 +#define AM_REG_CTIMER_STMINTCLR_COMPAREE_M 0x00000010 +#define AM_REG_CTIMER_STMINTCLR_COMPAREE(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_CTIMER_STMINTCLR_COMPAREE_COMPARED 0x00000010 + +// COUNTER is greater than or equal to COMPARE register D. +#define AM_REG_CTIMER_STMINTCLR_COMPARED_S 3 +#define AM_REG_CTIMER_STMINTCLR_COMPARED_M 0x00000008 +#define AM_REG_CTIMER_STMINTCLR_COMPARED(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_CTIMER_STMINTCLR_COMPARED_COMPARED 0x00000008 + +// COUNTER is greater than or equal to COMPARE register C. +#define AM_REG_CTIMER_STMINTCLR_COMPAREC_S 2 +#define AM_REG_CTIMER_STMINTCLR_COMPAREC_M 0x00000004 +#define AM_REG_CTIMER_STMINTCLR_COMPAREC(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_CTIMER_STMINTCLR_COMPAREC_COMPARED 0x00000004 + +// COUNTER is greater than or equal to COMPARE register B. +#define AM_REG_CTIMER_STMINTCLR_COMPAREB_S 1 +#define AM_REG_CTIMER_STMINTCLR_COMPAREB_M 0x00000002 +#define AM_REG_CTIMER_STMINTCLR_COMPAREB(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_CTIMER_STMINTCLR_COMPAREB_COMPARED 0x00000002 + +// COUNTER is greater than or equal to COMPARE register A. +#define AM_REG_CTIMER_STMINTCLR_COMPAREA_S 0 +#define AM_REG_CTIMER_STMINTCLR_COMPAREA_M 0x00000001 +#define AM_REG_CTIMER_STMINTCLR_COMPAREA(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_CTIMER_STMINTCLR_COMPAREA_COMPARED 0x00000001 + +//***************************************************************************** +// +// CTIMER_STMINTSET - STIMER Interrupt registers: Set +// +//***************************************************************************** +// CAPTURE register D has grabbed the value in the counter +#define AM_REG_CTIMER_STMINTSET_CAPTURED_S 12 +#define AM_REG_CTIMER_STMINTSET_CAPTURED_M 0x00001000 +#define AM_REG_CTIMER_STMINTSET_CAPTURED(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_CTIMER_STMINTSET_CAPTURED_CAPD_INT 0x00001000 + +// CAPTURE register C has grabbed the value in the counter +#define AM_REG_CTIMER_STMINTSET_CAPTUREC_S 11 +#define AM_REG_CTIMER_STMINTSET_CAPTUREC_M 0x00000800 +#define AM_REG_CTIMER_STMINTSET_CAPTUREC(n) (((uint32_t)(n) << 11) & 0x00000800) +#define AM_REG_CTIMER_STMINTSET_CAPTUREC_CAPC_INT 0x00000800 + +// CAPTURE register B has grabbed the value in the counter +#define AM_REG_CTIMER_STMINTSET_CAPTUREB_S 10 +#define AM_REG_CTIMER_STMINTSET_CAPTUREB_M 0x00000400 +#define AM_REG_CTIMER_STMINTSET_CAPTUREB(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_CTIMER_STMINTSET_CAPTUREB_CAPB_INT 0x00000400 + +// CAPTURE register A has grabbed the value in the counter +#define AM_REG_CTIMER_STMINTSET_CAPTUREA_S 9 +#define AM_REG_CTIMER_STMINTSET_CAPTUREA_M 0x00000200 +#define AM_REG_CTIMER_STMINTSET_CAPTUREA(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_CTIMER_STMINTSET_CAPTUREA_CAPA_INT 0x00000200 + +// COUNTER over flowed from 0xFFFFFFFF back to 0x00000000. +#define AM_REG_CTIMER_STMINTSET_OVERFLOW_S 8 +#define AM_REG_CTIMER_STMINTSET_OVERFLOW_M 0x00000100 +#define AM_REG_CTIMER_STMINTSET_OVERFLOW(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_CTIMER_STMINTSET_OVERFLOW_OFLOW_INT 0x00000100 + +// COUNTER is greater than or equal to COMPARE register H. +#define AM_REG_CTIMER_STMINTSET_COMPAREH_S 7 +#define AM_REG_CTIMER_STMINTSET_COMPAREH_M 0x00000080 +#define AM_REG_CTIMER_STMINTSET_COMPAREH(n) (((uint32_t)(n) << 7) & 0x00000080) +#define AM_REG_CTIMER_STMINTSET_COMPAREH_COMPARED 0x00000080 + +// COUNTER is greater than or equal to COMPARE register G. +#define AM_REG_CTIMER_STMINTSET_COMPAREG_S 6 +#define AM_REG_CTIMER_STMINTSET_COMPAREG_M 0x00000040 +#define AM_REG_CTIMER_STMINTSET_COMPAREG(n) (((uint32_t)(n) << 6) & 0x00000040) +#define AM_REG_CTIMER_STMINTSET_COMPAREG_COMPARED 0x00000040 + +// COUNTER is greater than or equal to COMPARE register F. +#define AM_REG_CTIMER_STMINTSET_COMPAREF_S 5 +#define AM_REG_CTIMER_STMINTSET_COMPAREF_M 0x00000020 +#define AM_REG_CTIMER_STMINTSET_COMPAREF(n) (((uint32_t)(n) << 5) & 0x00000020) +#define AM_REG_CTIMER_STMINTSET_COMPAREF_COMPARED 0x00000020 + +// COUNTER is greater than or equal to COMPARE register E. +#define AM_REG_CTIMER_STMINTSET_COMPAREE_S 4 +#define AM_REG_CTIMER_STMINTSET_COMPAREE_M 0x00000010 +#define AM_REG_CTIMER_STMINTSET_COMPAREE(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_CTIMER_STMINTSET_COMPAREE_COMPARED 0x00000010 + +// COUNTER is greater than or equal to COMPARE register D. +#define AM_REG_CTIMER_STMINTSET_COMPARED_S 3 +#define AM_REG_CTIMER_STMINTSET_COMPARED_M 0x00000008 +#define AM_REG_CTIMER_STMINTSET_COMPARED(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_CTIMER_STMINTSET_COMPARED_COMPARED 0x00000008 + +// COUNTER is greater than or equal to COMPARE register C. +#define AM_REG_CTIMER_STMINTSET_COMPAREC_S 2 +#define AM_REG_CTIMER_STMINTSET_COMPAREC_M 0x00000004 +#define AM_REG_CTIMER_STMINTSET_COMPAREC(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_CTIMER_STMINTSET_COMPAREC_COMPARED 0x00000004 + +// COUNTER is greater than or equal to COMPARE register B. +#define AM_REG_CTIMER_STMINTSET_COMPAREB_S 1 +#define AM_REG_CTIMER_STMINTSET_COMPAREB_M 0x00000002 +#define AM_REG_CTIMER_STMINTSET_COMPAREB(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_CTIMER_STMINTSET_COMPAREB_COMPARED 0x00000002 + +// COUNTER is greater than or equal to COMPARE register A. +#define AM_REG_CTIMER_STMINTSET_COMPAREA_S 0 +#define AM_REG_CTIMER_STMINTSET_COMPAREA_M 0x00000001 +#define AM_REG_CTIMER_STMINTSET_COMPAREA(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_CTIMER_STMINTSET_COMPAREA_COMPARED 0x00000001 + +//***************************************************************************** +// +// CTIMER_TMR0 - Counter/Timer Register +// +//***************************************************************************** +// Counter/Timer B0. +#define AM_REG_CTIMER_TMR0_CTTMRB0_S 16 +#define AM_REG_CTIMER_TMR0_CTTMRB0_M 0xFFFF0000 +#define AM_REG_CTIMER_TMR0_CTTMRB0(n) (((uint32_t)(n) << 16) & 0xFFFF0000) + +// Counter/Timer A0. +#define AM_REG_CTIMER_TMR0_CTTMRA0_S 0 +#define AM_REG_CTIMER_TMR0_CTTMRA0_M 0x0000FFFF +#define AM_REG_CTIMER_TMR0_CTTMRA0(n) (((uint32_t)(n) << 0) & 0x0000FFFF) + +//***************************************************************************** +// +// CTIMER_CMPRA0 - Counter/Timer A0 Compare Registers +// +//***************************************************************************** +// Counter/Timer A0 Compare Register 1. Holds the upper limit for timer half A. +#define AM_REG_CTIMER_CMPRA0_CMPR1A0_S 16 +#define AM_REG_CTIMER_CMPRA0_CMPR1A0_M 0xFFFF0000 +#define AM_REG_CTIMER_CMPRA0_CMPR1A0(n) (((uint32_t)(n) << 16) & 0xFFFF0000) + +// Counter/Timer A0 Compare Register 0. Holds the lower limit for timer half A. +#define AM_REG_CTIMER_CMPRA0_CMPR0A0_S 0 +#define AM_REG_CTIMER_CMPRA0_CMPR0A0_M 0x0000FFFF +#define AM_REG_CTIMER_CMPRA0_CMPR0A0(n) (((uint32_t)(n) << 0) & 0x0000FFFF) + +//***************************************************************************** +// +// CTIMER_CMPRB0 - Counter/Timer B0 Compare Registers +// +//***************************************************************************** +// Counter/Timer B0 Compare Register 1. Holds the upper limit for timer half B. +#define AM_REG_CTIMER_CMPRB0_CMPR1B0_S 16 +#define AM_REG_CTIMER_CMPRB0_CMPR1B0_M 0xFFFF0000 +#define AM_REG_CTIMER_CMPRB0_CMPR1B0(n) (((uint32_t)(n) << 16) & 0xFFFF0000) + +// Counter/Timer B0 Compare Register 0. Holds the lower limit for timer half B. +#define AM_REG_CTIMER_CMPRB0_CMPR0B0_S 0 +#define AM_REG_CTIMER_CMPRB0_CMPR0B0_M 0x0000FFFF +#define AM_REG_CTIMER_CMPRB0_CMPR0B0(n) (((uint32_t)(n) << 0) & 0x0000FFFF) + +//***************************************************************************** +// +// CTIMER_CTRL0 - Counter/Timer Control +// +//***************************************************************************** +// Counter/Timer A0/B0 Link bit. +#define AM_REG_CTIMER_CTRL0_CTLINK0_S 31 +#define AM_REG_CTIMER_CTRL0_CTLINK0_M 0x80000000 +#define AM_REG_CTIMER_CTRL0_CTLINK0(n) (((uint32_t)(n) << 31) & 0x80000000) +#define AM_REG_CTIMER_CTRL0_CTLINK0_TWO_16BIT_TIMERS 0x00000000 +#define AM_REG_CTIMER_CTRL0_CTLINK0_32BIT_TIMER 0x80000000 + +// Counter/Timer B0 Output Enable bit. +#define AM_REG_CTIMER_CTRL0_TMRB0PE_S 29 +#define AM_REG_CTIMER_CTRL0_TMRB0PE_M 0x20000000 +#define AM_REG_CTIMER_CTRL0_TMRB0PE(n) (((uint32_t)(n) << 29) & 0x20000000) +#define AM_REG_CTIMER_CTRL0_TMRB0PE_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL0_TMRB0PE_EN 0x20000000 + +// Counter/Timer B0 output polarity. +#define AM_REG_CTIMER_CTRL0_TMRB0POL_S 28 +#define AM_REG_CTIMER_CTRL0_TMRB0POL_M 0x10000000 +#define AM_REG_CTIMER_CTRL0_TMRB0POL(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_CTIMER_CTRL0_TMRB0POL_NORMAL 0x00000000 +#define AM_REG_CTIMER_CTRL0_TMRB0POL_INVERTED 0x10000000 + +// Counter/Timer B0 Clear bit. +#define AM_REG_CTIMER_CTRL0_TMRB0CLR_S 27 +#define AM_REG_CTIMER_CTRL0_TMRB0CLR_M 0x08000000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLR(n) (((uint32_t)(n) << 27) & 0x08000000) +#define AM_REG_CTIMER_CTRL0_TMRB0CLR_RUN 0x00000000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLR_CLEAR 0x08000000 + +// Counter/Timer B0 Interrupt Enable bit for COMPR1. +#define AM_REG_CTIMER_CTRL0_TMRB0IE1_S 26 +#define AM_REG_CTIMER_CTRL0_TMRB0IE1_M 0x04000000 +#define AM_REG_CTIMER_CTRL0_TMRB0IE1(n) (((uint32_t)(n) << 26) & 0x04000000) +#define AM_REG_CTIMER_CTRL0_TMRB0IE1_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL0_TMRB0IE1_EN 0x04000000 + +// Counter/Timer B0 Interrupt Enable bit for COMPR0. +#define AM_REG_CTIMER_CTRL0_TMRB0IE0_S 25 +#define AM_REG_CTIMER_CTRL0_TMRB0IE0_M 0x02000000 +#define AM_REG_CTIMER_CTRL0_TMRB0IE0(n) (((uint32_t)(n) << 25) & 0x02000000) +#define AM_REG_CTIMER_CTRL0_TMRB0IE0_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL0_TMRB0IE0_EN 0x02000000 + +// Counter/Timer B0 Function Select. +#define AM_REG_CTIMER_CTRL0_TMRB0FN_S 22 +#define AM_REG_CTIMER_CTRL0_TMRB0FN_M 0x01C00000 +#define AM_REG_CTIMER_CTRL0_TMRB0FN(n) (((uint32_t)(n) << 22) & 0x01C00000) +#define AM_REG_CTIMER_CTRL0_TMRB0FN_SINGLECOUNT 0x00000000 +#define AM_REG_CTIMER_CTRL0_TMRB0FN_REPEATEDCOUNT 0x00400000 +#define AM_REG_CTIMER_CTRL0_TMRB0FN_PULSE_ONCE 0x00800000 +#define AM_REG_CTIMER_CTRL0_TMRB0FN_PULSE_CONT 0x00C00000 +#define AM_REG_CTIMER_CTRL0_TMRB0FN_CONTINUOUS 0x01000000 + +// Counter/Timer B0 Clock Select. +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_S 17 +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_M 0x003E0000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLK(n) (((uint32_t)(n) << 17) & 0x003E0000) +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_TMRPIN 0x00000000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_HFRC_DIV4 0x00020000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_HFRC_DIV16 0x00040000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_HFRC_DIV256 0x00060000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_HFRC_DIV1024 0x00080000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_HFRC_DIV4K 0x000A0000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_XT 0x000C0000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_XT_DIV2 0x000E0000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_XT_DIV16 0x00100000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_XT_DIV256 0x00120000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_LFRC_DIV2 0x00140000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_LFRC_DIV32 0x00160000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_LFRC_DIV1K 0x00180000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_LFRC 0x001A0000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_RTC_100HZ 0x001C0000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_HCLK 0x001E0000 +#define AM_REG_CTIMER_CTRL0_TMRB0CLK_BUCKB 0x00200000 + +// Counter/Timer B0 Enable bit. +#define AM_REG_CTIMER_CTRL0_TMRB0EN_S 16 +#define AM_REG_CTIMER_CTRL0_TMRB0EN_M 0x00010000 +#define AM_REG_CTIMER_CTRL0_TMRB0EN(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_CTIMER_CTRL0_TMRB0EN_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL0_TMRB0EN_EN 0x00010000 + +// Counter/Timer A0 Output Enable bit. +#define AM_REG_CTIMER_CTRL0_TMRA0PE_S 13 +#define AM_REG_CTIMER_CTRL0_TMRA0PE_M 0x00002000 +#define AM_REG_CTIMER_CTRL0_TMRA0PE(n) (((uint32_t)(n) << 13) & 0x00002000) +#define AM_REG_CTIMER_CTRL0_TMRA0PE_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL0_TMRA0PE_EN 0x00002000 + +// Counter/Timer A0 output polarity. +#define AM_REG_CTIMER_CTRL0_TMRA0POL_S 12 +#define AM_REG_CTIMER_CTRL0_TMRA0POL_M 0x00001000 +#define AM_REG_CTIMER_CTRL0_TMRA0POL(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_CTIMER_CTRL0_TMRA0POL_NORMAL 0x00000000 +#define AM_REG_CTIMER_CTRL0_TMRA0POL_INVERTED 0x00001000 + +// Counter/Timer A0 Clear bit. +#define AM_REG_CTIMER_CTRL0_TMRA0CLR_S 11 +#define AM_REG_CTIMER_CTRL0_TMRA0CLR_M 0x00000800 +#define AM_REG_CTIMER_CTRL0_TMRA0CLR(n) (((uint32_t)(n) << 11) & 0x00000800) +#define AM_REG_CTIMER_CTRL0_TMRA0CLR_RUN 0x00000000 +#define AM_REG_CTIMER_CTRL0_TMRA0CLR_CLEAR 0x00000800 + +// Counter/Timer A0 Interrupt Enable bit based on COMPR1. +#define AM_REG_CTIMER_CTRL0_TMRA0IE1_S 10 +#define AM_REG_CTIMER_CTRL0_TMRA0IE1_M 0x00000400 +#define AM_REG_CTIMER_CTRL0_TMRA0IE1(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_CTIMER_CTRL0_TMRA0IE1_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL0_TMRA0IE1_EN 0x00000400 + +// Counter/Timer A0 Interrupt Enable bit based on COMPR0. +#define AM_REG_CTIMER_CTRL0_TMRA0IE0_S 9 +#define AM_REG_CTIMER_CTRL0_TMRA0IE0_M 0x00000200 +#define AM_REG_CTIMER_CTRL0_TMRA0IE0(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_CTIMER_CTRL0_TMRA0IE0_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL0_TMRA0IE0_EN 0x00000200 + +// Counter/Timer A0 Function Select. +#define AM_REG_CTIMER_CTRL0_TMRA0FN_S 6 +#define AM_REG_CTIMER_CTRL0_TMRA0FN_M 0x000001C0 +#define AM_REG_CTIMER_CTRL0_TMRA0FN(n) (((uint32_t)(n) << 6) & 0x000001C0) +#define AM_REG_CTIMER_CTRL0_TMRA0FN_SINGLECOUNT 0x00000000 +#define AM_REG_CTIMER_CTRL0_TMRA0FN_REPEATEDCOUNT 0x00000040 +#define AM_REG_CTIMER_CTRL0_TMRA0FN_PULSE_ONCE 0x00000080 +#define AM_REG_CTIMER_CTRL0_TMRA0FN_PULSE_CONT 0x000000C0 +#define AM_REG_CTIMER_CTRL0_TMRA0FN_CONTINUOUS 0x00000100 + +// Counter/Timer A0 Clock Select. +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_S 1 +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_M 0x0000003E +#define AM_REG_CTIMER_CTRL0_TMRA0CLK(n) (((uint32_t)(n) << 1) & 0x0000003E) +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_TMRPIN 0x00000000 +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_HFRC_DIV4 0x00000002 +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_HFRC_DIV16 0x00000004 +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_HFRC_DIV256 0x00000006 +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_HFRC_DIV1024 0x00000008 +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_HFRC_DIV4K 0x0000000A +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_XT 0x0000000C +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_XT_DIV2 0x0000000E +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_XT_DIV16 0x00000010 +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_XT_DIV256 0x00000012 +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_LFRC_DIV2 0x00000014 +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_LFRC_DIV32 0x00000016 +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_LFRC_DIV1K 0x00000018 +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_LFRC 0x0000001A +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_RTC_100HZ 0x0000001C +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_HCLK_DIV4 0x0000001E +#define AM_REG_CTIMER_CTRL0_TMRA0CLK_BUCKA 0x00000020 + +// Counter/Timer A0 Enable bit. +#define AM_REG_CTIMER_CTRL0_TMRA0EN_S 0 +#define AM_REG_CTIMER_CTRL0_TMRA0EN_M 0x00000001 +#define AM_REG_CTIMER_CTRL0_TMRA0EN(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_CTIMER_CTRL0_TMRA0EN_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL0_TMRA0EN_EN 0x00000001 + +//***************************************************************************** +// +// CTIMER_TMR1 - Counter/Timer Register +// +//***************************************************************************** +// Counter/Timer B1. +#define AM_REG_CTIMER_TMR1_CTTMRB1_S 16 +#define AM_REG_CTIMER_TMR1_CTTMRB1_M 0xFFFF0000 +#define AM_REG_CTIMER_TMR1_CTTMRB1(n) (((uint32_t)(n) << 16) & 0xFFFF0000) + +// Counter/Timer A1. +#define AM_REG_CTIMER_TMR1_CTTMRA1_S 0 +#define AM_REG_CTIMER_TMR1_CTTMRA1_M 0x0000FFFF +#define AM_REG_CTIMER_TMR1_CTTMRA1(n) (((uint32_t)(n) << 0) & 0x0000FFFF) + +//***************************************************************************** +// +// CTIMER_CMPRA1 - Counter/Timer A1 Compare Registers +// +//***************************************************************************** +// Counter/Timer A1 Compare Register 1. +#define AM_REG_CTIMER_CMPRA1_CMPR1A1_S 16 +#define AM_REG_CTIMER_CMPRA1_CMPR1A1_M 0xFFFF0000 +#define AM_REG_CTIMER_CMPRA1_CMPR1A1(n) (((uint32_t)(n) << 16) & 0xFFFF0000) + +// Counter/Timer A1 Compare Register 0. +#define AM_REG_CTIMER_CMPRA1_CMPR0A1_S 0 +#define AM_REG_CTIMER_CMPRA1_CMPR0A1_M 0x0000FFFF +#define AM_REG_CTIMER_CMPRA1_CMPR0A1(n) (((uint32_t)(n) << 0) & 0x0000FFFF) + +//***************************************************************************** +// +// CTIMER_CMPRB1 - Counter/Timer B1 Compare Registers +// +//***************************************************************************** +// Counter/Timer B1 Compare Register 1. +#define AM_REG_CTIMER_CMPRB1_CMPR1B1_S 16 +#define AM_REG_CTIMER_CMPRB1_CMPR1B1_M 0xFFFF0000 +#define AM_REG_CTIMER_CMPRB1_CMPR1B1(n) (((uint32_t)(n) << 16) & 0xFFFF0000) + +// Counter/Timer B1 Compare Register 0. +#define AM_REG_CTIMER_CMPRB1_CMPR0B1_S 0 +#define AM_REG_CTIMER_CMPRB1_CMPR0B1_M 0x0000FFFF +#define AM_REG_CTIMER_CMPRB1_CMPR0B1(n) (((uint32_t)(n) << 0) & 0x0000FFFF) + +//***************************************************************************** +// +// CTIMER_CTRL1 - Counter/Timer Control +// +//***************************************************************************** +// Counter/Timer A1/B1 Link bit. +#define AM_REG_CTIMER_CTRL1_CTLINK1_S 31 +#define AM_REG_CTIMER_CTRL1_CTLINK1_M 0x80000000 +#define AM_REG_CTIMER_CTRL1_CTLINK1(n) (((uint32_t)(n) << 31) & 0x80000000) +#define AM_REG_CTIMER_CTRL1_CTLINK1_TWO_16BIT_TIMERS 0x00000000 +#define AM_REG_CTIMER_CTRL1_CTLINK1_32BIT_TIMER 0x80000000 + +// Counter/Timer B1 Output Enable bit. +#define AM_REG_CTIMER_CTRL1_TMRB1PE_S 29 +#define AM_REG_CTIMER_CTRL1_TMRB1PE_M 0x20000000 +#define AM_REG_CTIMER_CTRL1_TMRB1PE(n) (((uint32_t)(n) << 29) & 0x20000000) +#define AM_REG_CTIMER_CTRL1_TMRB1PE_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL1_TMRB1PE_EN 0x20000000 + +// Counter/Timer B1 output polarity. +#define AM_REG_CTIMER_CTRL1_TMRB1POL_S 28 +#define AM_REG_CTIMER_CTRL1_TMRB1POL_M 0x10000000 +#define AM_REG_CTIMER_CTRL1_TMRB1POL(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_CTIMER_CTRL1_TMRB1POL_NORMAL 0x00000000 +#define AM_REG_CTIMER_CTRL1_TMRB1POL_INVERTED 0x10000000 + +// Counter/Timer B1 Clear bit. +#define AM_REG_CTIMER_CTRL1_TMRB1CLR_S 27 +#define AM_REG_CTIMER_CTRL1_TMRB1CLR_M 0x08000000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLR(n) (((uint32_t)(n) << 27) & 0x08000000) +#define AM_REG_CTIMER_CTRL1_TMRB1CLR_RUN 0x00000000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLR_CLEAR 0x08000000 + +// Counter/Timer B1 Interrupt Enable bit for COMPR1. +#define AM_REG_CTIMER_CTRL1_TMRB1IE1_S 26 +#define AM_REG_CTIMER_CTRL1_TMRB1IE1_M 0x04000000 +#define AM_REG_CTIMER_CTRL1_TMRB1IE1(n) (((uint32_t)(n) << 26) & 0x04000000) +#define AM_REG_CTIMER_CTRL1_TMRB1IE1_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL1_TMRB1IE1_EN 0x04000000 + +// Counter/Timer B1 Interrupt Enable bit for COMPR0. +#define AM_REG_CTIMER_CTRL1_TMRB1IE0_S 25 +#define AM_REG_CTIMER_CTRL1_TMRB1IE0_M 0x02000000 +#define AM_REG_CTIMER_CTRL1_TMRB1IE0(n) (((uint32_t)(n) << 25) & 0x02000000) +#define AM_REG_CTIMER_CTRL1_TMRB1IE0_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL1_TMRB1IE0_EN 0x02000000 + +// Counter/Timer B1 Function Select. +#define AM_REG_CTIMER_CTRL1_TMRB1FN_S 22 +#define AM_REG_CTIMER_CTRL1_TMRB1FN_M 0x01C00000 +#define AM_REG_CTIMER_CTRL1_TMRB1FN(n) (((uint32_t)(n) << 22) & 0x01C00000) +#define AM_REG_CTIMER_CTRL1_TMRB1FN_SINGLECOUNT 0x00000000 +#define AM_REG_CTIMER_CTRL1_TMRB1FN_REPEATEDCOUNT 0x00400000 +#define AM_REG_CTIMER_CTRL1_TMRB1FN_PULSE_ONCE 0x00800000 +#define AM_REG_CTIMER_CTRL1_TMRB1FN_PULSE_CONT 0x00C00000 +#define AM_REG_CTIMER_CTRL1_TMRB1FN_CONTINUOUS 0x01000000 + +// Counter/Timer B1 Clock Select. +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_S 17 +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_M 0x003E0000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLK(n) (((uint32_t)(n) << 17) & 0x003E0000) +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_TMRPIN 0x00000000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_HFRC_DIV4 0x00020000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_HFRC_DIV16 0x00040000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_HFRC_DIV256 0x00060000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_HFRC_DIV1024 0x00080000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_HFRC_DIV4K 0x000A0000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_XT 0x000C0000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_XT_DIV2 0x000E0000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_XT_DIV16 0x00100000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_XT_DIV256 0x00120000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_LFRC_DIV2 0x00140000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_LFRC_DIV32 0x00160000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_LFRC_DIV1K 0x00180000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_LFRC 0x001A0000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_RTC_100HZ 0x001C0000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_HCLK 0x001E0000 +#define AM_REG_CTIMER_CTRL1_TMRB1CLK_BUCKB 0x00200000 + +// Counter/Timer B1 Enable bit. +#define AM_REG_CTIMER_CTRL1_TMRB1EN_S 16 +#define AM_REG_CTIMER_CTRL1_TMRB1EN_M 0x00010000 +#define AM_REG_CTIMER_CTRL1_TMRB1EN(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_CTIMER_CTRL1_TMRB1EN_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL1_TMRB1EN_EN 0x00010000 + +// Counter/Timer A1 Output Enable bit. +#define AM_REG_CTIMER_CTRL1_TMRA1PE_S 13 +#define AM_REG_CTIMER_CTRL1_TMRA1PE_M 0x00002000 +#define AM_REG_CTIMER_CTRL1_TMRA1PE(n) (((uint32_t)(n) << 13) & 0x00002000) +#define AM_REG_CTIMER_CTRL1_TMRA1PE_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL1_TMRA1PE_EN 0x00002000 + +// Counter/Timer A1 output polarity. +#define AM_REG_CTIMER_CTRL1_TMRA1POL_S 12 +#define AM_REG_CTIMER_CTRL1_TMRA1POL_M 0x00001000 +#define AM_REG_CTIMER_CTRL1_TMRA1POL(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_CTIMER_CTRL1_TMRA1POL_NORMAL 0x00000000 +#define AM_REG_CTIMER_CTRL1_TMRA1POL_INVERTED 0x00001000 + +// Counter/Timer A1 Clear bit. +#define AM_REG_CTIMER_CTRL1_TMRA1CLR_S 11 +#define AM_REG_CTIMER_CTRL1_TMRA1CLR_M 0x00000800 +#define AM_REG_CTIMER_CTRL1_TMRA1CLR(n) (((uint32_t)(n) << 11) & 0x00000800) +#define AM_REG_CTIMER_CTRL1_TMRA1CLR_RUN 0x00000000 +#define AM_REG_CTIMER_CTRL1_TMRA1CLR_CLEAR 0x00000800 + +// Counter/Timer A1 Interrupt Enable bit based on COMPR1. +#define AM_REG_CTIMER_CTRL1_TMRA1IE1_S 10 +#define AM_REG_CTIMER_CTRL1_TMRA1IE1_M 0x00000400 +#define AM_REG_CTIMER_CTRL1_TMRA1IE1(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_CTIMER_CTRL1_TMRA1IE1_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL1_TMRA1IE1_EN 0x00000400 + +// Counter/Timer A1 Interrupt Enable bit based on COMPR0. +#define AM_REG_CTIMER_CTRL1_TMRA1IE0_S 9 +#define AM_REG_CTIMER_CTRL1_TMRA1IE0_M 0x00000200 +#define AM_REG_CTIMER_CTRL1_TMRA1IE0(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_CTIMER_CTRL1_TMRA1IE0_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL1_TMRA1IE0_EN 0x00000200 + +// Counter/Timer A1 Function Select. +#define AM_REG_CTIMER_CTRL1_TMRA1FN_S 6 +#define AM_REG_CTIMER_CTRL1_TMRA1FN_M 0x000001C0 +#define AM_REG_CTIMER_CTRL1_TMRA1FN(n) (((uint32_t)(n) << 6) & 0x000001C0) +#define AM_REG_CTIMER_CTRL1_TMRA1FN_SINGLECOUNT 0x00000000 +#define AM_REG_CTIMER_CTRL1_TMRA1FN_REPEATEDCOUNT 0x00000040 +#define AM_REG_CTIMER_CTRL1_TMRA1FN_PULSE_ONCE 0x00000080 +#define AM_REG_CTIMER_CTRL1_TMRA1FN_PULSE_CONT 0x000000C0 +#define AM_REG_CTIMER_CTRL1_TMRA1FN_CONTINUOUS 0x00000100 + +// Counter/Timer A1 Clock Select. +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_S 1 +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_M 0x0000003E +#define AM_REG_CTIMER_CTRL1_TMRA1CLK(n) (((uint32_t)(n) << 1) & 0x0000003E) +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_TMRPIN 0x00000000 +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_HFRC_DIV4 0x00000002 +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_HFRC_DIV16 0x00000004 +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_HFRC_DIV256 0x00000006 +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_HFRC_DIV1024 0x00000008 +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_HFRC_DIV4K 0x0000000A +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_XT 0x0000000C +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_XT_DIV2 0x0000000E +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_XT_DIV16 0x00000010 +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_XT_DIV256 0x00000012 +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_LFRC_DIV2 0x00000014 +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_LFRC_DIV32 0x00000016 +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_LFRC_DIV1K 0x00000018 +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_LFRC 0x0000001A +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_RTC_100HZ 0x0000001C +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_HCLK 0x0000001E +#define AM_REG_CTIMER_CTRL1_TMRA1CLK_BUCKA 0x00000020 + +// Counter/Timer A1 Enable bit. +#define AM_REG_CTIMER_CTRL1_TMRA1EN_S 0 +#define AM_REG_CTIMER_CTRL1_TMRA1EN_M 0x00000001 +#define AM_REG_CTIMER_CTRL1_TMRA1EN(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_CTIMER_CTRL1_TMRA1EN_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL1_TMRA1EN_EN 0x00000001 + +//***************************************************************************** +// +// CTIMER_TMR2 - Counter/Timer Register +// +//***************************************************************************** +// Counter/Timer B2. +#define AM_REG_CTIMER_TMR2_CTTMRB2_S 16 +#define AM_REG_CTIMER_TMR2_CTTMRB2_M 0xFFFF0000 +#define AM_REG_CTIMER_TMR2_CTTMRB2(n) (((uint32_t)(n) << 16) & 0xFFFF0000) + +// Counter/Timer A2. +#define AM_REG_CTIMER_TMR2_CTTMRA2_S 0 +#define AM_REG_CTIMER_TMR2_CTTMRA2_M 0x0000FFFF +#define AM_REG_CTIMER_TMR2_CTTMRA2(n) (((uint32_t)(n) << 0) & 0x0000FFFF) + +//***************************************************************************** +// +// CTIMER_CMPRA2 - Counter/Timer A2 Compare Registers +// +//***************************************************************************** +// Counter/Timer A2 Compare Register 1. +#define AM_REG_CTIMER_CMPRA2_CMPR1A2_S 16 +#define AM_REG_CTIMER_CMPRA2_CMPR1A2_M 0xFFFF0000 +#define AM_REG_CTIMER_CMPRA2_CMPR1A2(n) (((uint32_t)(n) << 16) & 0xFFFF0000) + +// Counter/Timer A2 Compare Register 0. +#define AM_REG_CTIMER_CMPRA2_CMPR0A2_S 0 +#define AM_REG_CTIMER_CMPRA2_CMPR0A2_M 0x0000FFFF +#define AM_REG_CTIMER_CMPRA2_CMPR0A2(n) (((uint32_t)(n) << 0) & 0x0000FFFF) + +//***************************************************************************** +// +// CTIMER_CMPRB2 - Counter/Timer B2 Compare Registers +// +//***************************************************************************** +// Counter/Timer B2 Compare Register 1. +#define AM_REG_CTIMER_CMPRB2_CMPR1B2_S 16 +#define AM_REG_CTIMER_CMPRB2_CMPR1B2_M 0xFFFF0000 +#define AM_REG_CTIMER_CMPRB2_CMPR1B2(n) (((uint32_t)(n) << 16) & 0xFFFF0000) + +// Counter/Timer B2 Compare Register 0. +#define AM_REG_CTIMER_CMPRB2_CMPR0B2_S 0 +#define AM_REG_CTIMER_CMPRB2_CMPR0B2_M 0x0000FFFF +#define AM_REG_CTIMER_CMPRB2_CMPR0B2(n) (((uint32_t)(n) << 0) & 0x0000FFFF) + +//***************************************************************************** +// +// CTIMER_CTRL2 - Counter/Timer Control +// +//***************************************************************************** +// Counter/Timer A2/B2 Link bit. +#define AM_REG_CTIMER_CTRL2_CTLINK2_S 31 +#define AM_REG_CTIMER_CTRL2_CTLINK2_M 0x80000000 +#define AM_REG_CTIMER_CTRL2_CTLINK2(n) (((uint32_t)(n) << 31) & 0x80000000) +#define AM_REG_CTIMER_CTRL2_CTLINK2_TWO_16BIT_TIMERS 0x00000000 +#define AM_REG_CTIMER_CTRL2_CTLINK2_32BIT_TIMER 0x80000000 + +// Counter/Timer B2 Output Enable bit. +#define AM_REG_CTIMER_CTRL2_TMRB2PE_S 29 +#define AM_REG_CTIMER_CTRL2_TMRB2PE_M 0x20000000 +#define AM_REG_CTIMER_CTRL2_TMRB2PE(n) (((uint32_t)(n) << 29) & 0x20000000) +#define AM_REG_CTIMER_CTRL2_TMRB2PE_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL2_TMRB2PE_EN 0x20000000 + +// Counter/Timer B2 output polarity. +#define AM_REG_CTIMER_CTRL2_TMRB2POL_S 28 +#define AM_REG_CTIMER_CTRL2_TMRB2POL_M 0x10000000 +#define AM_REG_CTIMER_CTRL2_TMRB2POL(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_CTIMER_CTRL2_TMRB2POL_NORMAL 0x00000000 +#define AM_REG_CTIMER_CTRL2_TMRB2POL_INVERTED 0x10000000 + +// Counter/Timer B2 Clear bit. +#define AM_REG_CTIMER_CTRL2_TMRB2CLR_S 27 +#define AM_REG_CTIMER_CTRL2_TMRB2CLR_M 0x08000000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLR(n) (((uint32_t)(n) << 27) & 0x08000000) +#define AM_REG_CTIMER_CTRL2_TMRB2CLR_RUN 0x00000000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLR_CLEAR 0x08000000 + +// Counter/Timer B2 Interrupt Enable bit for COMPR1. +#define AM_REG_CTIMER_CTRL2_TMRB2IE1_S 26 +#define AM_REG_CTIMER_CTRL2_TMRB2IE1_M 0x04000000 +#define AM_REG_CTIMER_CTRL2_TMRB2IE1(n) (((uint32_t)(n) << 26) & 0x04000000) +#define AM_REG_CTIMER_CTRL2_TMRB2IE1_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL2_TMRB2IE1_EN 0x04000000 + +// Counter/Timer B2 Interrupt Enable bit for COMPR0. +#define AM_REG_CTIMER_CTRL2_TMRB2IE0_S 25 +#define AM_REG_CTIMER_CTRL2_TMRB2IE0_M 0x02000000 +#define AM_REG_CTIMER_CTRL2_TMRB2IE0(n) (((uint32_t)(n) << 25) & 0x02000000) +#define AM_REG_CTIMER_CTRL2_TMRB2IE0_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL2_TMRB2IE0_EN 0x02000000 + +// Counter/Timer B2 Function Select. +#define AM_REG_CTIMER_CTRL2_TMRB2FN_S 22 +#define AM_REG_CTIMER_CTRL2_TMRB2FN_M 0x01C00000 +#define AM_REG_CTIMER_CTRL2_TMRB2FN(n) (((uint32_t)(n) << 22) & 0x01C00000) +#define AM_REG_CTIMER_CTRL2_TMRB2FN_SINGLECOUNT 0x00000000 +#define AM_REG_CTIMER_CTRL2_TMRB2FN_REPEATEDCOUNT 0x00400000 +#define AM_REG_CTIMER_CTRL2_TMRB2FN_PULSE_ONCE 0x00800000 +#define AM_REG_CTIMER_CTRL2_TMRB2FN_PULSE_CONT 0x00C00000 +#define AM_REG_CTIMER_CTRL2_TMRB2FN_CONTINUOUS 0x01000000 + +// Counter/Timer B2 Clock Select. +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_S 17 +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_M 0x003E0000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLK(n) (((uint32_t)(n) << 17) & 0x003E0000) +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_TMRPIN 0x00000000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_HFRC_DIV4 0x00020000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_HFRC_DIV16 0x00040000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_HFRC_DIV256 0x00060000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_HFRC_DIV1024 0x00080000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_HFRC_DIV4K 0x000A0000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_XT 0x000C0000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_XT_DIV2 0x000E0000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_XT_DIV16 0x00100000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_XT_DIV256 0x00120000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_LFRC_DIV2 0x00140000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_LFRC_DIV32 0x00160000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_LFRC_DIV1K 0x00180000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_LFRC 0x001A0000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_RTC_100HZ 0x001C0000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_HCLK 0x001E0000 +#define AM_REG_CTIMER_CTRL2_TMRB2CLK_BUCKA 0x00200000 + +// Counter/Timer B2 Enable bit. +#define AM_REG_CTIMER_CTRL2_TMRB2EN_S 16 +#define AM_REG_CTIMER_CTRL2_TMRB2EN_M 0x00010000 +#define AM_REG_CTIMER_CTRL2_TMRB2EN(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_CTIMER_CTRL2_TMRB2EN_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL2_TMRB2EN_EN 0x00010000 + +// Counter/Timer A2 Output Enable bit. +#define AM_REG_CTIMER_CTRL2_TMRA2PE_S 13 +#define AM_REG_CTIMER_CTRL2_TMRA2PE_M 0x00002000 +#define AM_REG_CTIMER_CTRL2_TMRA2PE(n) (((uint32_t)(n) << 13) & 0x00002000) +#define AM_REG_CTIMER_CTRL2_TMRA2PE_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL2_TMRA2PE_EN 0x00002000 + +// Counter/Timer A2 output polarity. +#define AM_REG_CTIMER_CTRL2_TMRA2POL_S 12 +#define AM_REG_CTIMER_CTRL2_TMRA2POL_M 0x00001000 +#define AM_REG_CTIMER_CTRL2_TMRA2POL(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_CTIMER_CTRL2_TMRA2POL_NORMAL 0x00000000 +#define AM_REG_CTIMER_CTRL2_TMRA2POL_INVERTED 0x00001000 + +// Counter/Timer A2 Clear bit. +#define AM_REG_CTIMER_CTRL2_TMRA2CLR_S 11 +#define AM_REG_CTIMER_CTRL2_TMRA2CLR_M 0x00000800 +#define AM_REG_CTIMER_CTRL2_TMRA2CLR(n) (((uint32_t)(n) << 11) & 0x00000800) +#define AM_REG_CTIMER_CTRL2_TMRA2CLR_RUN 0x00000000 +#define AM_REG_CTIMER_CTRL2_TMRA2CLR_CLEAR 0x00000800 + +// Counter/Timer A2 Interrupt Enable bit based on COMPR1. +#define AM_REG_CTIMER_CTRL2_TMRA2IE1_S 10 +#define AM_REG_CTIMER_CTRL2_TMRA2IE1_M 0x00000400 +#define AM_REG_CTIMER_CTRL2_TMRA2IE1(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_CTIMER_CTRL2_TMRA2IE1_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL2_TMRA2IE1_EN 0x00000400 + +// Counter/Timer A2 Interrupt Enable bit based on COMPR0. +#define AM_REG_CTIMER_CTRL2_TMRA2IE0_S 9 +#define AM_REG_CTIMER_CTRL2_TMRA2IE0_M 0x00000200 +#define AM_REG_CTIMER_CTRL2_TMRA2IE0(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_CTIMER_CTRL2_TMRA2IE0_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL2_TMRA2IE0_EN 0x00000200 + +// Counter/Timer A2 Function Select. +#define AM_REG_CTIMER_CTRL2_TMRA2FN_S 6 +#define AM_REG_CTIMER_CTRL2_TMRA2FN_M 0x000001C0 +#define AM_REG_CTIMER_CTRL2_TMRA2FN(n) (((uint32_t)(n) << 6) & 0x000001C0) +#define AM_REG_CTIMER_CTRL2_TMRA2FN_SINGLECOUNT 0x00000000 +#define AM_REG_CTIMER_CTRL2_TMRA2FN_REPEATEDCOUNT 0x00000040 +#define AM_REG_CTIMER_CTRL2_TMRA2FN_PULSE_ONCE 0x00000080 +#define AM_REG_CTIMER_CTRL2_TMRA2FN_PULSE_CONT 0x000000C0 +#define AM_REG_CTIMER_CTRL2_TMRA2FN_CONTINUOUS 0x00000100 + +// Counter/Timer A2 Clock Select. +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_S 1 +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_M 0x0000003E +#define AM_REG_CTIMER_CTRL2_TMRA2CLK(n) (((uint32_t)(n) << 1) & 0x0000003E) +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_TMRPIN 0x00000000 +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_HFRC_DIV4 0x00000002 +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_HFRC_DIV16 0x00000004 +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_HFRC_DIV256 0x00000006 +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_HFRC_DIV1024 0x00000008 +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_HFRC_DIV4K 0x0000000A +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_XT 0x0000000C +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_XT_DIV2 0x0000000E +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_XT_DIV16 0x00000010 +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_XT_DIV256 0x00000012 +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_LFRC_DIV2 0x00000014 +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_LFRC_DIV32 0x00000016 +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_LFRC_DIV1K 0x00000018 +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_LFRC 0x0000001A +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_RTC_100HZ 0x0000001C +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_HCLK 0x0000001E +#define AM_REG_CTIMER_CTRL2_TMRA2CLK_BUCKB 0x00000020 + +// Counter/Timer A2 Enable bit. +#define AM_REG_CTIMER_CTRL2_TMRA2EN_S 0 +#define AM_REG_CTIMER_CTRL2_TMRA2EN_M 0x00000001 +#define AM_REG_CTIMER_CTRL2_TMRA2EN(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_CTIMER_CTRL2_TMRA2EN_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL2_TMRA2EN_EN 0x00000001 + +//***************************************************************************** +// +// CTIMER_TMR3 - Counter/Timer Register +// +//***************************************************************************** +// Counter/Timer B3. +#define AM_REG_CTIMER_TMR3_CTTMRB3_S 16 +#define AM_REG_CTIMER_TMR3_CTTMRB3_M 0xFFFF0000 +#define AM_REG_CTIMER_TMR3_CTTMRB3(n) (((uint32_t)(n) << 16) & 0xFFFF0000) + +// Counter/Timer A3. +#define AM_REG_CTIMER_TMR3_CTTMRA3_S 0 +#define AM_REG_CTIMER_TMR3_CTTMRA3_M 0x0000FFFF +#define AM_REG_CTIMER_TMR3_CTTMRA3(n) (((uint32_t)(n) << 0) & 0x0000FFFF) + +//***************************************************************************** +// +// CTIMER_CMPRA3 - Counter/Timer A3 Compare Registers +// +//***************************************************************************** +// Counter/Timer A3 Compare Register 1. +#define AM_REG_CTIMER_CMPRA3_CMPR1A3_S 16 +#define AM_REG_CTIMER_CMPRA3_CMPR1A3_M 0xFFFF0000 +#define AM_REG_CTIMER_CMPRA3_CMPR1A3(n) (((uint32_t)(n) << 16) & 0xFFFF0000) + +// Counter/Timer A3 Compare Register 0. +#define AM_REG_CTIMER_CMPRA3_CMPR0A3_S 0 +#define AM_REG_CTIMER_CMPRA3_CMPR0A3_M 0x0000FFFF +#define AM_REG_CTIMER_CMPRA3_CMPR0A3(n) (((uint32_t)(n) << 0) & 0x0000FFFF) + +//***************************************************************************** +// +// CTIMER_CMPRB3 - Counter/Timer B3 Compare Registers +// +//***************************************************************************** +// Counter/Timer B3 Compare Register 1. +#define AM_REG_CTIMER_CMPRB3_CMPR1B3_S 16 +#define AM_REG_CTIMER_CMPRB3_CMPR1B3_M 0xFFFF0000 +#define AM_REG_CTIMER_CMPRB3_CMPR1B3(n) (((uint32_t)(n) << 16) & 0xFFFF0000) + +// Counter/Timer B3 Compare Register 0. +#define AM_REG_CTIMER_CMPRB3_CMPR0B3_S 0 +#define AM_REG_CTIMER_CMPRB3_CMPR0B3_M 0x0000FFFF +#define AM_REG_CTIMER_CMPRB3_CMPR0B3(n) (((uint32_t)(n) << 0) & 0x0000FFFF) + +//***************************************************************************** +// +// CTIMER_CTRL3 - Counter/Timer Control +// +//***************************************************************************** +// Counter/Timer A3/B3 Link bit. +#define AM_REG_CTIMER_CTRL3_CTLINK3_S 31 +#define AM_REG_CTIMER_CTRL3_CTLINK3_M 0x80000000 +#define AM_REG_CTIMER_CTRL3_CTLINK3(n) (((uint32_t)(n) << 31) & 0x80000000) +#define AM_REG_CTIMER_CTRL3_CTLINK3_TWO_16BIT_TIMERS 0x00000000 +#define AM_REG_CTIMER_CTRL3_CTLINK3_32BIT_TIMER 0x80000000 + +// Counter/Timer B3 Output Enable bit. +#define AM_REG_CTIMER_CTRL3_TMRB3PE_S 29 +#define AM_REG_CTIMER_CTRL3_TMRB3PE_M 0x20000000 +#define AM_REG_CTIMER_CTRL3_TMRB3PE(n) (((uint32_t)(n) << 29) & 0x20000000) +#define AM_REG_CTIMER_CTRL3_TMRB3PE_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL3_TMRB3PE_EN 0x20000000 + +// Counter/Timer B3 output polarity. +#define AM_REG_CTIMER_CTRL3_TMRB3POL_S 28 +#define AM_REG_CTIMER_CTRL3_TMRB3POL_M 0x10000000 +#define AM_REG_CTIMER_CTRL3_TMRB3POL(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_CTIMER_CTRL3_TMRB3POL_NORMAL 0x00000000 +#define AM_REG_CTIMER_CTRL3_TMRB3POL_INVERTED 0x10000000 + +// Counter/Timer B3 Clear bit. +#define AM_REG_CTIMER_CTRL3_TMRB3CLR_S 27 +#define AM_REG_CTIMER_CTRL3_TMRB3CLR_M 0x08000000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLR(n) (((uint32_t)(n) << 27) & 0x08000000) +#define AM_REG_CTIMER_CTRL3_TMRB3CLR_RUN 0x00000000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLR_CLEAR 0x08000000 + +// Counter/Timer B3 Interrupt Enable bit for COMPR1. +#define AM_REG_CTIMER_CTRL3_TMRB3IE1_S 26 +#define AM_REG_CTIMER_CTRL3_TMRB3IE1_M 0x04000000 +#define AM_REG_CTIMER_CTRL3_TMRB3IE1(n) (((uint32_t)(n) << 26) & 0x04000000) +#define AM_REG_CTIMER_CTRL3_TMRB3IE1_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL3_TMRB3IE1_EN 0x04000000 + +// Counter/Timer B3 Interrupt Enable bit for COMPR0. +#define AM_REG_CTIMER_CTRL3_TMRB3IE0_S 25 +#define AM_REG_CTIMER_CTRL3_TMRB3IE0_M 0x02000000 +#define AM_REG_CTIMER_CTRL3_TMRB3IE0(n) (((uint32_t)(n) << 25) & 0x02000000) +#define AM_REG_CTIMER_CTRL3_TMRB3IE0_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL3_TMRB3IE0_EN 0x02000000 + +// Counter/Timer B3 Function Select. +#define AM_REG_CTIMER_CTRL3_TMRB3FN_S 22 +#define AM_REG_CTIMER_CTRL3_TMRB3FN_M 0x01C00000 +#define AM_REG_CTIMER_CTRL3_TMRB3FN(n) (((uint32_t)(n) << 22) & 0x01C00000) +#define AM_REG_CTIMER_CTRL3_TMRB3FN_SINGLECOUNT 0x00000000 +#define AM_REG_CTIMER_CTRL3_TMRB3FN_REPEATEDCOUNT 0x00400000 +#define AM_REG_CTIMER_CTRL3_TMRB3FN_PULSE_ONCE 0x00800000 +#define AM_REG_CTIMER_CTRL3_TMRB3FN_PULSE_CONT 0x00C00000 +#define AM_REG_CTIMER_CTRL3_TMRB3FN_CONTINUOUS 0x01000000 + +// Counter/Timer B3 Clock Select. +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_S 17 +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_M 0x003E0000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLK(n) (((uint32_t)(n) << 17) & 0x003E0000) +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_TMRPIN 0x00000000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_HFRC_DIV4 0x00020000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_HFRC_DIV16 0x00040000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_HFRC_DIV256 0x00060000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_HFRC_DIV1024 0x00080000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_HFRC_DIV4K 0x000A0000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_XT 0x000C0000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_XT_DIV2 0x000E0000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_XT_DIV16 0x00100000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_XT_DIV256 0x00120000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_LFRC_DIV2 0x00140000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_LFRC_DIV32 0x00160000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_LFRC_DIV1K 0x00180000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_LFRC 0x001A0000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_RTC_100HZ 0x001C0000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_HCLK 0x001E0000 +#define AM_REG_CTIMER_CTRL3_TMRB3CLK_BUCKA 0x00200000 + +// Counter/Timer B3 Enable bit. +#define AM_REG_CTIMER_CTRL3_TMRB3EN_S 16 +#define AM_REG_CTIMER_CTRL3_TMRB3EN_M 0x00010000 +#define AM_REG_CTIMER_CTRL3_TMRB3EN(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_CTIMER_CTRL3_TMRB3EN_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL3_TMRB3EN_EN 0x00010000 + +// Special Timer A3 enable for ADC function. +#define AM_REG_CTIMER_CTRL3_ADCEN_S 15 +#define AM_REG_CTIMER_CTRL3_ADCEN_M 0x00008000 +#define AM_REG_CTIMER_CTRL3_ADCEN(n) (((uint32_t)(n) << 15) & 0x00008000) + +// Counter/Timer A3 Output Enable bit. +#define AM_REG_CTIMER_CTRL3_TMRA3PE_S 13 +#define AM_REG_CTIMER_CTRL3_TMRA3PE_M 0x00002000 +#define AM_REG_CTIMER_CTRL3_TMRA3PE(n) (((uint32_t)(n) << 13) & 0x00002000) +#define AM_REG_CTIMER_CTRL3_TMRA3PE_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL3_TMRA3PE_EN 0x00002000 + +// Counter/Timer A3 output polarity. +#define AM_REG_CTIMER_CTRL3_TMRA3POL_S 12 +#define AM_REG_CTIMER_CTRL3_TMRA3POL_M 0x00001000 +#define AM_REG_CTIMER_CTRL3_TMRA3POL(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_CTIMER_CTRL3_TMRA3POL_NORMAL 0x00000000 +#define AM_REG_CTIMER_CTRL3_TMRA3POL_INVERTED 0x00001000 + +// Counter/Timer A3 Clear bit. +#define AM_REG_CTIMER_CTRL3_TMRA3CLR_S 11 +#define AM_REG_CTIMER_CTRL3_TMRA3CLR_M 0x00000800 +#define AM_REG_CTIMER_CTRL3_TMRA3CLR(n) (((uint32_t)(n) << 11) & 0x00000800) +#define AM_REG_CTIMER_CTRL3_TMRA3CLR_RUN 0x00000000 +#define AM_REG_CTIMER_CTRL3_TMRA3CLR_CLEAR 0x00000800 + +// Counter/Timer A3 Interrupt Enable bit based on COMPR1. +#define AM_REG_CTIMER_CTRL3_TMRA3IE1_S 10 +#define AM_REG_CTIMER_CTRL3_TMRA3IE1_M 0x00000400 +#define AM_REG_CTIMER_CTRL3_TMRA3IE1(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_CTIMER_CTRL3_TMRA3IE1_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL3_TMRA3IE1_EN 0x00000400 + +// Counter/Timer A3 Interrupt Enable bit based on COMPR0. +#define AM_REG_CTIMER_CTRL3_TMRA3IE0_S 9 +#define AM_REG_CTIMER_CTRL3_TMRA3IE0_M 0x00000200 +#define AM_REG_CTIMER_CTRL3_TMRA3IE0(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_CTIMER_CTRL3_TMRA3IE0_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL3_TMRA3IE0_EN 0x00000200 + +// Counter/Timer A3 Function Select. +#define AM_REG_CTIMER_CTRL3_TMRA3FN_S 6 +#define AM_REG_CTIMER_CTRL3_TMRA3FN_M 0x000001C0 +#define AM_REG_CTIMER_CTRL3_TMRA3FN(n) (((uint32_t)(n) << 6) & 0x000001C0) +#define AM_REG_CTIMER_CTRL3_TMRA3FN_SINGLECOUNT 0x00000000 +#define AM_REG_CTIMER_CTRL3_TMRA3FN_REPEATEDCOUNT 0x00000040 +#define AM_REG_CTIMER_CTRL3_TMRA3FN_PULSE_ONCE 0x00000080 +#define AM_REG_CTIMER_CTRL3_TMRA3FN_PULSE_CONT 0x000000C0 +#define AM_REG_CTIMER_CTRL3_TMRA3FN_CONTINUOUS 0x00000100 + +// Counter/Timer A3 Clock Select. +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_S 1 +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_M 0x0000003E +#define AM_REG_CTIMER_CTRL3_TMRA3CLK(n) (((uint32_t)(n) << 1) & 0x0000003E) +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_TMRPIN 0x00000000 +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_HFRC_DIV4 0x00000002 +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_HFRC_DIV16 0x00000004 +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_HFRC_DIV256 0x00000006 +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_HFRC_DIV1024 0x00000008 +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_HFRC_DIV4K 0x0000000A +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_XT 0x0000000C +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_XT_DIV2 0x0000000E +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_XT_DIV16 0x00000010 +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_XT_DIV256 0x00000012 +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_LFRC_DIV2 0x00000014 +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_LFRC_DIV32 0x00000016 +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_LFRC_DIV1K 0x00000018 +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_LFRC 0x0000001A +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_RTC_100HZ 0x0000001C +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_HCLK 0x0000001E +#define AM_REG_CTIMER_CTRL3_TMRA3CLK_BUCKB 0x00000020 + +// Counter/Timer A3 Enable bit. +#define AM_REG_CTIMER_CTRL3_TMRA3EN_S 0 +#define AM_REG_CTIMER_CTRL3_TMRA3EN_M 0x00000001 +#define AM_REG_CTIMER_CTRL3_TMRA3EN(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_CTIMER_CTRL3_TMRA3EN_DIS 0x00000000 +#define AM_REG_CTIMER_CTRL3_TMRA3EN_EN 0x00000001 + +//***************************************************************************** +// +// CTIMER_STCFG - Configuration Register +// +//***************************************************************************** +// Set this bit to one to freeze the clock input to the COUNTER register. Once +// frozen, the value can be safely written from the MCU. Unfreeze to resume. +#define AM_REG_CTIMER_STCFG_FREEZE_S 31 +#define AM_REG_CTIMER_STCFG_FREEZE_M 0x80000000 +#define AM_REG_CTIMER_STCFG_FREEZE(n) (((uint32_t)(n) << 31) & 0x80000000) +#define AM_REG_CTIMER_STCFG_FREEZE_THAW 0x00000000 +#define AM_REG_CTIMER_STCFG_FREEZE_FREEZE 0x80000000 + +// Set this bit to one to clear the System Timer register. If this bit is set +// to '1', the system timer register will stay cleared. It needs to be set to +// '0' for the system timer to start running. +#define AM_REG_CTIMER_STCFG_CLEAR_S 30 +#define AM_REG_CTIMER_STCFG_CLEAR_M 0x40000000 +#define AM_REG_CTIMER_STCFG_CLEAR(n) (((uint32_t)(n) << 30) & 0x40000000) +#define AM_REG_CTIMER_STCFG_CLEAR_RUN 0x00000000 +#define AM_REG_CTIMER_STCFG_CLEAR_CLEAR 0x40000000 + +// Selects whether compare is enabled for the corresponding SCMPR register. If +// compare is enabled, the interrupt status is set once the comparision is met. +#define AM_REG_CTIMER_STCFG_COMPARE_H_EN_S 15 +#define AM_REG_CTIMER_STCFG_COMPARE_H_EN_M 0x00008000 +#define AM_REG_CTIMER_STCFG_COMPARE_H_EN(n) (((uint32_t)(n) << 15) & 0x00008000) +#define AM_REG_CTIMER_STCFG_COMPARE_H_EN_DISABLE 0x00000000 +#define AM_REG_CTIMER_STCFG_COMPARE_H_EN_ENABLE 0x00008000 + +// Selects whether compare is enabled for the corresponding SCMPR register. If +// compare is enabled, the interrupt status is set once the comparision is met. +#define AM_REG_CTIMER_STCFG_COMPARE_G_EN_S 14 +#define AM_REG_CTIMER_STCFG_COMPARE_G_EN_M 0x00004000 +#define AM_REG_CTIMER_STCFG_COMPARE_G_EN(n) (((uint32_t)(n) << 14) & 0x00004000) +#define AM_REG_CTIMER_STCFG_COMPARE_G_EN_DISABLE 0x00000000 +#define AM_REG_CTIMER_STCFG_COMPARE_G_EN_ENABLE 0x00004000 + +// Selects whether compare is enabled for the corresponding SCMPR register. If +// compare is enabled, the interrupt status is set once the comparision is met. +#define AM_REG_CTIMER_STCFG_COMPARE_F_EN_S 13 +#define AM_REG_CTIMER_STCFG_COMPARE_F_EN_M 0x00002000 +#define AM_REG_CTIMER_STCFG_COMPARE_F_EN(n) (((uint32_t)(n) << 13) & 0x00002000) +#define AM_REG_CTIMER_STCFG_COMPARE_F_EN_DISABLE 0x00000000 +#define AM_REG_CTIMER_STCFG_COMPARE_F_EN_ENABLE 0x00002000 + +// Selects whether compare is enabled for the corresponding SCMPR register. If +// compare is enabled, the interrupt status is set once the comparision is met. +#define AM_REG_CTIMER_STCFG_COMPARE_E_EN_S 12 +#define AM_REG_CTIMER_STCFG_COMPARE_E_EN_M 0x00001000 +#define AM_REG_CTIMER_STCFG_COMPARE_E_EN(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_CTIMER_STCFG_COMPARE_E_EN_DISABLE 0x00000000 +#define AM_REG_CTIMER_STCFG_COMPARE_E_EN_ENABLE 0x00001000 + +// Selects whether compare is enabled for the corresponding SCMPR register. If +// compare is enabled, the interrupt status is set once the comparision is met. +#define AM_REG_CTIMER_STCFG_COMPARE_D_EN_S 11 +#define AM_REG_CTIMER_STCFG_COMPARE_D_EN_M 0x00000800 +#define AM_REG_CTIMER_STCFG_COMPARE_D_EN(n) (((uint32_t)(n) << 11) & 0x00000800) +#define AM_REG_CTIMER_STCFG_COMPARE_D_EN_DISABLE 0x00000000 +#define AM_REG_CTIMER_STCFG_COMPARE_D_EN_ENABLE 0x00000800 + +// Selects whether compare is enabled for the corresponding SCMPR register. If +// compare is enabled, the interrupt status is set once the comparision is met. +#define AM_REG_CTIMER_STCFG_COMPARE_C_EN_S 10 +#define AM_REG_CTIMER_STCFG_COMPARE_C_EN_M 0x00000400 +#define AM_REG_CTIMER_STCFG_COMPARE_C_EN(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_CTIMER_STCFG_COMPARE_C_EN_DISABLE 0x00000000 +#define AM_REG_CTIMER_STCFG_COMPARE_C_EN_ENABLE 0x00000400 + +// Selects whether compare is enabled for the corresponding SCMPR register. If +// compare is enabled, the interrupt status is set once the comparision is met. +#define AM_REG_CTIMER_STCFG_COMPARE_B_EN_S 9 +#define AM_REG_CTIMER_STCFG_COMPARE_B_EN_M 0x00000200 +#define AM_REG_CTIMER_STCFG_COMPARE_B_EN(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_CTIMER_STCFG_COMPARE_B_EN_DISABLE 0x00000000 +#define AM_REG_CTIMER_STCFG_COMPARE_B_EN_ENABLE 0x00000200 + +// Selects whether compare is enabled for the corresponding SCMPR register. If +// compare is enabled, the interrupt status is set once the comparision is met. +#define AM_REG_CTIMER_STCFG_COMPARE_A_EN_S 8 +#define AM_REG_CTIMER_STCFG_COMPARE_A_EN_M 0x00000100 +#define AM_REG_CTIMER_STCFG_COMPARE_A_EN(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_CTIMER_STCFG_COMPARE_A_EN_DISABLE 0x00000000 +#define AM_REG_CTIMER_STCFG_COMPARE_A_EN_ENABLE 0x00000100 + +// Selects an appropriate clock source and divider to use for the System Timer +// clock. +#define AM_REG_CTIMER_STCFG_CLKSEL_S 0 +#define AM_REG_CTIMER_STCFG_CLKSEL_M 0x0000000F +#define AM_REG_CTIMER_STCFG_CLKSEL(n) (((uint32_t)(n) << 0) & 0x0000000F) +#define AM_REG_CTIMER_STCFG_CLKSEL_NOCLK 0x00000000 +#define AM_REG_CTIMER_STCFG_CLKSEL_HFRC_DIV16 0x00000001 +#define AM_REG_CTIMER_STCFG_CLKSEL_HFRC_DIV256 0x00000002 +#define AM_REG_CTIMER_STCFG_CLKSEL_XTAL_DIV1 0x00000003 +#define AM_REG_CTIMER_STCFG_CLKSEL_XTAL_DIV2 0x00000004 +#define AM_REG_CTIMER_STCFG_CLKSEL_XTAL_DIV32 0x00000005 +#define AM_REG_CTIMER_STCFG_CLKSEL_LFRC_DIV1 0x00000006 +#define AM_REG_CTIMER_STCFG_CLKSEL_CTIMER0A 0x00000007 +#define AM_REG_CTIMER_STCFG_CLKSEL_CTIMER0B 0x00000008 + +//***************************************************************************** +// +// CTIMER_STTMR - System Timer Count Register (Real Time Counter) +// +//***************************************************************************** +// Value of the 32-bit counter as it ticks over. +#define AM_REG_CTIMER_STTMR_VALUE_S 0 +#define AM_REG_CTIMER_STTMR_VALUE_M 0xFFFFFFFF +#define AM_REG_CTIMER_STTMR_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CTIMER_CAPTURE_CONTROL - Capture Control Register +// +//***************************************************************************** +// Selects whether capture is enabled for the specified capture register. +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_D_S 3 +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_D_M 0x00000008 +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_D(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_D_DISABLE 0x00000000 +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_D_ENABLE 0x00000008 + +// Selects whether capture is enabled for the specified capture register. +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_C_S 2 +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_C_M 0x00000004 +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_C(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_C_DISABLE 0x00000000 +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_C_ENABLE 0x00000004 + +// Selects whether capture is enabled for the specified capture register. +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_B_S 1 +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_B_M 0x00000002 +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_B(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_B_DISABLE 0x00000000 +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_B_ENABLE 0x00000002 + +// Selects whether capture is enabled for the specified capture register. +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_A_S 0 +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_A_M 0x00000001 +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_A(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_A_DISABLE 0x00000000 +#define AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_A_ENABLE 0x00000001 + +//***************************************************************************** +// +// CTIMER_SCMPR0 - Compare Register A +// +//***************************************************************************** +// Compare this value to the value in the COUNTER register according to the +// match criterion, as selected in the COMPARE_A_EN bit in the REG_CTIMER_STCGF +// register. +#define AM_REG_CTIMER_SCMPR0_VALUE_S 0 +#define AM_REG_CTIMER_SCMPR0_VALUE_M 0xFFFFFFFF +#define AM_REG_CTIMER_SCMPR0_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CTIMER_SCMPR1 - Compare Register B +// +//***************************************************************************** +// Compare this value to the value in the COUNTER register according to the +// match criterion, as selected in the COMPARE_B_EN bit in the REG_CTIMER_STCGF +// register. +#define AM_REG_CTIMER_SCMPR1_VALUE_S 0 +#define AM_REG_CTIMER_SCMPR1_VALUE_M 0xFFFFFFFF +#define AM_REG_CTIMER_SCMPR1_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CTIMER_SCMPR2 - Compare Register C +// +//***************************************************************************** +// Compare this value to the value in the COUNTER register according to the +// match criterion, as selected in the COMPARE_C_EN bit in the REG_CTIMER_STCGF +// register. +#define AM_REG_CTIMER_SCMPR2_VALUE_S 0 +#define AM_REG_CTIMER_SCMPR2_VALUE_M 0xFFFFFFFF +#define AM_REG_CTIMER_SCMPR2_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CTIMER_SCMPR3 - Compare Register D +// +//***************************************************************************** +// Compare this value to the value in the COUNTER register according to the +// match criterion, as selected in the COMPARE_D_EN bit in the REG_CTIMER_STCGF +// register. +#define AM_REG_CTIMER_SCMPR3_VALUE_S 0 +#define AM_REG_CTIMER_SCMPR3_VALUE_M 0xFFFFFFFF +#define AM_REG_CTIMER_SCMPR3_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CTIMER_SCMPR4 - Compare Register E +// +//***************************************************************************** +// Compare this value to the value in the COUNTER register according to the +// match criterion, as selected in the COMPARE_E_EN bit in the REG_CTIMER_STCGF +// register. +#define AM_REG_CTIMER_SCMPR4_VALUE_S 0 +#define AM_REG_CTIMER_SCMPR4_VALUE_M 0xFFFFFFFF +#define AM_REG_CTIMER_SCMPR4_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CTIMER_SCMPR5 - Compare Register F +// +//***************************************************************************** +// Compare this value to the value in the COUNTER register according to the +// match criterion, as selected in the COMPARE_F_EN bit in the REG_CTIMER_STCGF +// register. +#define AM_REG_CTIMER_SCMPR5_VALUE_S 0 +#define AM_REG_CTIMER_SCMPR5_VALUE_M 0xFFFFFFFF +#define AM_REG_CTIMER_SCMPR5_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CTIMER_SCMPR6 - Compare Register G +// +//***************************************************************************** +// Compare this value to the value in the COUNTER register according to the +// match criterion, as selected in the COMPARE_G_EN bit in the REG_CTIMER_STCGF +// register. +#define AM_REG_CTIMER_SCMPR6_VALUE_S 0 +#define AM_REG_CTIMER_SCMPR6_VALUE_M 0xFFFFFFFF +#define AM_REG_CTIMER_SCMPR6_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CTIMER_SCMPR7 - Compare Register H +// +//***************************************************************************** +// Compare this value to the value in the COUNTER register according to the +// match criterion, as selected in the COMPARE_H_EN bit in the REG_CTIMER_STCGF +// register. +#define AM_REG_CTIMER_SCMPR7_VALUE_S 0 +#define AM_REG_CTIMER_SCMPR7_VALUE_M 0xFFFFFFFF +#define AM_REG_CTIMER_SCMPR7_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CTIMER_SCAPT0 - Capture Register A +// +//***************************************************************************** +// Whenever the event is detected, the value in the COUNTER is copied into this +// register and the corresponding interrupt status bit is set. +#define AM_REG_CTIMER_SCAPT0_VALUE_S 0 +#define AM_REG_CTIMER_SCAPT0_VALUE_M 0xFFFFFFFF +#define AM_REG_CTIMER_SCAPT0_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CTIMER_SCAPT1 - Capture Register B +// +//***************************************************************************** +// Whenever the event is detected, the value in the COUNTER is copied into this +// register and the corresponding interrupt status bit is set. +#define AM_REG_CTIMER_SCAPT1_VALUE_S 0 +#define AM_REG_CTIMER_SCAPT1_VALUE_M 0xFFFFFFFF +#define AM_REG_CTIMER_SCAPT1_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CTIMER_SCAPT2 - Capture Register C +// +//***************************************************************************** +// Whenever the event is detected, the value in the COUNTER is copied into this +// register and the corresponding interrupt status bit is set. +#define AM_REG_CTIMER_SCAPT2_VALUE_S 0 +#define AM_REG_CTIMER_SCAPT2_VALUE_M 0xFFFFFFFF +#define AM_REG_CTIMER_SCAPT2_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CTIMER_SCAPT3 - Capture Register D +// +//***************************************************************************** +// Whenever the event is detected, the value in the COUNTER is copied into this +// register and the corresponding interrupt status bit is set. +#define AM_REG_CTIMER_SCAPT3_VALUE_S 0 +#define AM_REG_CTIMER_SCAPT3_VALUE_M 0xFFFFFFFF +#define AM_REG_CTIMER_SCAPT3_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CTIMER_SNVR0 - System Timer NVRAM_A Register +// +//***************************************************************************** +// Value of the 32-bit counter as it ticks over. +#define AM_REG_CTIMER_SNVR0_VALUE_S 0 +#define AM_REG_CTIMER_SNVR0_VALUE_M 0xFFFFFFFF +#define AM_REG_CTIMER_SNVR0_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CTIMER_SNVR1 - System Timer NVRAM_B Register +// +//***************************************************************************** +// Value of the 32-bit counter as it ticks over. +#define AM_REG_CTIMER_SNVR1_VALUE_S 0 +#define AM_REG_CTIMER_SNVR1_VALUE_M 0xFFFFFFFF +#define AM_REG_CTIMER_SNVR1_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// CTIMER_SNVR2 - System Timer NVRAM_C Register +// +//***************************************************************************** +// Value of the 32-bit counter as it ticks over. +#define AM_REG_CTIMER_SNVR2_VALUE_S 0 +#define AM_REG_CTIMER_SNVR2_VALUE_M 0xFFFFFFFF +#define AM_REG_CTIMER_SNVR2_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +#endif // AM_REG_CTIMER_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_flashctrl.h b/bsp/apollo2/libraries/drivers/regs/am_reg_flashctrl.h new file mode 100644 index 0000000000..0b103ea6fb --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_flashctrl.h @@ -0,0 +1,68 @@ +//***************************************************************************** +// +// am_reg_flashctrl.h +//! @file +//! +//! @brief Register macros for the FLASHCTRL module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_FLASHCTRL_H +#define AM_REG_FLASHCTRL_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_FLASHCTRL_NUM_MODULES 1 +#define AM_REG_FLASHCTRLn(n) \ + (REG_FLASHCTRL_BASEADDR + 0x00001000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** + +//***************************************************************************** +// +// Key values. +// +//***************************************************************************** + +#endif // AM_REG_FLASHCTRL_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_gpio.h b/bsp/apollo2/libraries/drivers/regs/am_reg_gpio.h new file mode 100644 index 0000000000..4690cd6111 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_gpio.h @@ -0,0 +1,5218 @@ +//***************************************************************************** +// +// am_reg_gpio.h +//! @file +//! +//! @brief Register macros for the GPIO module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_GPIO_H +#define AM_REG_GPIO_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_GPIO_NUM_MODULES 1 +#define AM_REG_GPIOn(n) \ + (REG_GPIO_BASEADDR + 0x00000000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_GPIO_PADREGA_O 0x00000000 +#define AM_REG_GPIO_PADREGB_O 0x00000004 +#define AM_REG_GPIO_PADREGC_O 0x00000008 +#define AM_REG_GPIO_PADREGD_O 0x0000000C +#define AM_REG_GPIO_PADREGE_O 0x00000010 +#define AM_REG_GPIO_PADREGF_O 0x00000014 +#define AM_REG_GPIO_PADREGG_O 0x00000018 +#define AM_REG_GPIO_PADREGH_O 0x0000001C +#define AM_REG_GPIO_PADREGI_O 0x00000020 +#define AM_REG_GPIO_PADREGJ_O 0x00000024 +#define AM_REG_GPIO_PADREGK_O 0x00000028 +#define AM_REG_GPIO_PADREGL_O 0x0000002C +#define AM_REG_GPIO_PADREGM_O 0x00000030 +#define AM_REG_GPIO_CFGA_O 0x00000040 +#define AM_REG_GPIO_CFGB_O 0x00000044 +#define AM_REG_GPIO_CFGC_O 0x00000048 +#define AM_REG_GPIO_CFGD_O 0x0000004C +#define AM_REG_GPIO_CFGE_O 0x00000050 +#define AM_REG_GPIO_CFGF_O 0x00000054 +#define AM_REG_GPIO_CFGG_O 0x00000058 +#define AM_REG_GPIO_RDA_O 0x00000080 +#define AM_REG_GPIO_RDB_O 0x00000084 +#define AM_REG_GPIO_WTA_O 0x00000088 +#define AM_REG_GPIO_WTB_O 0x0000008C +#define AM_REG_GPIO_WTSA_O 0x00000090 +#define AM_REG_GPIO_WTSB_O 0x00000094 +#define AM_REG_GPIO_WTCA_O 0x00000098 +#define AM_REG_GPIO_WTCB_O 0x0000009C +#define AM_REG_GPIO_ENA_O 0x000000A0 +#define AM_REG_GPIO_ENB_O 0x000000A4 +#define AM_REG_GPIO_ENSA_O 0x000000A8 +#define AM_REG_GPIO_ENSB_O 0x000000AC +#define AM_REG_GPIO_ENCA_O 0x000000B4 +#define AM_REG_GPIO_ENCB_O 0x000000B8 +#define AM_REG_GPIO_STMRCAP_O 0x000000BC +#define AM_REG_GPIO_IOM0IRQ_O 0x000000C0 +#define AM_REG_GPIO_IOM1IRQ_O 0x000000C4 +#define AM_REG_GPIO_IOM2IRQ_O 0x000000C8 +#define AM_REG_GPIO_IOM3IRQ_O 0x000000CC +#define AM_REG_GPIO_IOM4IRQ_O 0x000000D0 +#define AM_REG_GPIO_IOM5IRQ_O 0x000000D4 +#define AM_REG_GPIO_LOOPBACK_O 0x000000D8 +#define AM_REG_GPIO_GPIOOBS_O 0x000000DC +#define AM_REG_GPIO_ALTPADCFGA_O 0x000000E0 +#define AM_REG_GPIO_ALTPADCFGB_O 0x000000E4 +#define AM_REG_GPIO_ALTPADCFGC_O 0x000000E8 +#define AM_REG_GPIO_ALTPADCFGD_O 0x000000EC +#define AM_REG_GPIO_ALTPADCFGE_O 0x000000F0 +#define AM_REG_GPIO_ALTPADCFGF_O 0x000000F4 +#define AM_REG_GPIO_ALTPADCFGG_O 0x000000F8 +#define AM_REG_GPIO_ALTPADCFGH_O 0x000000FC +#define AM_REG_GPIO_ALTPADCFGI_O 0x00000100 +#define AM_REG_GPIO_ALTPADCFGJ_O 0x00000104 +#define AM_REG_GPIO_ALTPADCFGK_O 0x00000108 +#define AM_REG_GPIO_ALTPADCFGL_O 0x0000010C +#define AM_REG_GPIO_ALTPADCFGM_O 0x00000110 +#define AM_REG_GPIO_PADKEY_O 0x00000060 +#define AM_REG_GPIO_INT0EN_O 0x00000200 +#define AM_REG_GPIO_INT0STAT_O 0x00000204 +#define AM_REG_GPIO_INT0CLR_O 0x00000208 +#define AM_REG_GPIO_INT0SET_O 0x0000020C +#define AM_REG_GPIO_INT1EN_O 0x00000210 +#define AM_REG_GPIO_INT1STAT_O 0x00000214 +#define AM_REG_GPIO_INT1CLR_O 0x00000218 +#define AM_REG_GPIO_INT1SET_O 0x0000021C + +//***************************************************************************** +// +// Key values. +// +//***************************************************************************** +#define AM_REG_GPIO_PADKEY_KEYVAL 0x00000073 + +//***************************************************************************** +// +// GPIO_INT0EN - GPIO Interrupt Registers 31-0: Enable +// +//***************************************************************************** +// GPIO31 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO31_S 31 +#define AM_REG_GPIO_INT0EN_GPIO31_M 0x80000000 +#define AM_REG_GPIO_INT0EN_GPIO31(n) (((uint32_t)(n) << 31) & 0x80000000) + +// GPIO30 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO30_S 30 +#define AM_REG_GPIO_INT0EN_GPIO30_M 0x40000000 +#define AM_REG_GPIO_INT0EN_GPIO30(n) (((uint32_t)(n) << 30) & 0x40000000) + +// GPIO29 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO29_S 29 +#define AM_REG_GPIO_INT0EN_GPIO29_M 0x20000000 +#define AM_REG_GPIO_INT0EN_GPIO29(n) (((uint32_t)(n) << 29) & 0x20000000) + +// GPIO28 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO28_S 28 +#define AM_REG_GPIO_INT0EN_GPIO28_M 0x10000000 +#define AM_REG_GPIO_INT0EN_GPIO28(n) (((uint32_t)(n) << 28) & 0x10000000) + +// GPIO27 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO27_S 27 +#define AM_REG_GPIO_INT0EN_GPIO27_M 0x08000000 +#define AM_REG_GPIO_INT0EN_GPIO27(n) (((uint32_t)(n) << 27) & 0x08000000) + +// GPIO26 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO26_S 26 +#define AM_REG_GPIO_INT0EN_GPIO26_M 0x04000000 +#define AM_REG_GPIO_INT0EN_GPIO26(n) (((uint32_t)(n) << 26) & 0x04000000) + +// GPIO25 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO25_S 25 +#define AM_REG_GPIO_INT0EN_GPIO25_M 0x02000000 +#define AM_REG_GPIO_INT0EN_GPIO25(n) (((uint32_t)(n) << 25) & 0x02000000) + +// GPIO24 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO24_S 24 +#define AM_REG_GPIO_INT0EN_GPIO24_M 0x01000000 +#define AM_REG_GPIO_INT0EN_GPIO24(n) (((uint32_t)(n) << 24) & 0x01000000) + +// GPIO23 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO23_S 23 +#define AM_REG_GPIO_INT0EN_GPIO23_M 0x00800000 +#define AM_REG_GPIO_INT0EN_GPIO23(n) (((uint32_t)(n) << 23) & 0x00800000) + +// GPIO22 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO22_S 22 +#define AM_REG_GPIO_INT0EN_GPIO22_M 0x00400000 +#define AM_REG_GPIO_INT0EN_GPIO22(n) (((uint32_t)(n) << 22) & 0x00400000) + +// GPIO21 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO21_S 21 +#define AM_REG_GPIO_INT0EN_GPIO21_M 0x00200000 +#define AM_REG_GPIO_INT0EN_GPIO21(n) (((uint32_t)(n) << 21) & 0x00200000) + +// GPIO20 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO20_S 20 +#define AM_REG_GPIO_INT0EN_GPIO20_M 0x00100000 +#define AM_REG_GPIO_INT0EN_GPIO20(n) (((uint32_t)(n) << 20) & 0x00100000) + +// GPIO19 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO19_S 19 +#define AM_REG_GPIO_INT0EN_GPIO19_M 0x00080000 +#define AM_REG_GPIO_INT0EN_GPIO19(n) (((uint32_t)(n) << 19) & 0x00080000) + +// GPIO18interrupt. +#define AM_REG_GPIO_INT0EN_GPIO18_S 18 +#define AM_REG_GPIO_INT0EN_GPIO18_M 0x00040000 +#define AM_REG_GPIO_INT0EN_GPIO18(n) (((uint32_t)(n) << 18) & 0x00040000) + +// GPIO17 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO17_S 17 +#define AM_REG_GPIO_INT0EN_GPIO17_M 0x00020000 +#define AM_REG_GPIO_INT0EN_GPIO17(n) (((uint32_t)(n) << 17) & 0x00020000) + +// GPIO16 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO16_S 16 +#define AM_REG_GPIO_INT0EN_GPIO16_M 0x00010000 +#define AM_REG_GPIO_INT0EN_GPIO16(n) (((uint32_t)(n) << 16) & 0x00010000) + +// GPIO15 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO15_S 15 +#define AM_REG_GPIO_INT0EN_GPIO15_M 0x00008000 +#define AM_REG_GPIO_INT0EN_GPIO15(n) (((uint32_t)(n) << 15) & 0x00008000) + +// GPIO14 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO14_S 14 +#define AM_REG_GPIO_INT0EN_GPIO14_M 0x00004000 +#define AM_REG_GPIO_INT0EN_GPIO14(n) (((uint32_t)(n) << 14) & 0x00004000) + +// GPIO13 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO13_S 13 +#define AM_REG_GPIO_INT0EN_GPIO13_M 0x00002000 +#define AM_REG_GPIO_INT0EN_GPIO13(n) (((uint32_t)(n) << 13) & 0x00002000) + +// GPIO12 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO12_S 12 +#define AM_REG_GPIO_INT0EN_GPIO12_M 0x00001000 +#define AM_REG_GPIO_INT0EN_GPIO12(n) (((uint32_t)(n) << 12) & 0x00001000) + +// GPIO11 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO11_S 11 +#define AM_REG_GPIO_INT0EN_GPIO11_M 0x00000800 +#define AM_REG_GPIO_INT0EN_GPIO11(n) (((uint32_t)(n) << 11) & 0x00000800) + +// GPIO10 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO10_S 10 +#define AM_REG_GPIO_INT0EN_GPIO10_M 0x00000400 +#define AM_REG_GPIO_INT0EN_GPIO10(n) (((uint32_t)(n) << 10) & 0x00000400) + +// GPIO9 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO9_S 9 +#define AM_REG_GPIO_INT0EN_GPIO9_M 0x00000200 +#define AM_REG_GPIO_INT0EN_GPIO9(n) (((uint32_t)(n) << 9) & 0x00000200) + +// GPIO8 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO8_S 8 +#define AM_REG_GPIO_INT0EN_GPIO8_M 0x00000100 +#define AM_REG_GPIO_INT0EN_GPIO8(n) (((uint32_t)(n) << 8) & 0x00000100) + +// GPIO7 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO7_S 7 +#define AM_REG_GPIO_INT0EN_GPIO7_M 0x00000080 +#define AM_REG_GPIO_INT0EN_GPIO7(n) (((uint32_t)(n) << 7) & 0x00000080) + +// GPIO6 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO6_S 6 +#define AM_REG_GPIO_INT0EN_GPIO6_M 0x00000040 +#define AM_REG_GPIO_INT0EN_GPIO6(n) (((uint32_t)(n) << 6) & 0x00000040) + +// GPIO5 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO5_S 5 +#define AM_REG_GPIO_INT0EN_GPIO5_M 0x00000020 +#define AM_REG_GPIO_INT0EN_GPIO5(n) (((uint32_t)(n) << 5) & 0x00000020) + +// GPIO4 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO4_S 4 +#define AM_REG_GPIO_INT0EN_GPIO4_M 0x00000010 +#define AM_REG_GPIO_INT0EN_GPIO4(n) (((uint32_t)(n) << 4) & 0x00000010) + +// GPIO3 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO3_S 3 +#define AM_REG_GPIO_INT0EN_GPIO3_M 0x00000008 +#define AM_REG_GPIO_INT0EN_GPIO3(n) (((uint32_t)(n) << 3) & 0x00000008) + +// GPIO2 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO2_S 2 +#define AM_REG_GPIO_INT0EN_GPIO2_M 0x00000004 +#define AM_REG_GPIO_INT0EN_GPIO2(n) (((uint32_t)(n) << 2) & 0x00000004) + +// GPIO1 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO1_S 1 +#define AM_REG_GPIO_INT0EN_GPIO1_M 0x00000002 +#define AM_REG_GPIO_INT0EN_GPIO1(n) (((uint32_t)(n) << 1) & 0x00000002) + +// GPIO0 interrupt. +#define AM_REG_GPIO_INT0EN_GPIO0_S 0 +#define AM_REG_GPIO_INT0EN_GPIO0_M 0x00000001 +#define AM_REG_GPIO_INT0EN_GPIO0(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_INT0STAT - GPIO Interrupt Registers 31-0: Status +// +//***************************************************************************** +// GPIO31 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO31_S 31 +#define AM_REG_GPIO_INT0STAT_GPIO31_M 0x80000000 +#define AM_REG_GPIO_INT0STAT_GPIO31(n) (((uint32_t)(n) << 31) & 0x80000000) + +// GPIO30 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO30_S 30 +#define AM_REG_GPIO_INT0STAT_GPIO30_M 0x40000000 +#define AM_REG_GPIO_INT0STAT_GPIO30(n) (((uint32_t)(n) << 30) & 0x40000000) + +// GPIO29 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO29_S 29 +#define AM_REG_GPIO_INT0STAT_GPIO29_M 0x20000000 +#define AM_REG_GPIO_INT0STAT_GPIO29(n) (((uint32_t)(n) << 29) & 0x20000000) + +// GPIO28 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO28_S 28 +#define AM_REG_GPIO_INT0STAT_GPIO28_M 0x10000000 +#define AM_REG_GPIO_INT0STAT_GPIO28(n) (((uint32_t)(n) << 28) & 0x10000000) + +// GPIO27 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO27_S 27 +#define AM_REG_GPIO_INT0STAT_GPIO27_M 0x08000000 +#define AM_REG_GPIO_INT0STAT_GPIO27(n) (((uint32_t)(n) << 27) & 0x08000000) + +// GPIO26 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO26_S 26 +#define AM_REG_GPIO_INT0STAT_GPIO26_M 0x04000000 +#define AM_REG_GPIO_INT0STAT_GPIO26(n) (((uint32_t)(n) << 26) & 0x04000000) + +// GPIO25 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO25_S 25 +#define AM_REG_GPIO_INT0STAT_GPIO25_M 0x02000000 +#define AM_REG_GPIO_INT0STAT_GPIO25(n) (((uint32_t)(n) << 25) & 0x02000000) + +// GPIO24 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO24_S 24 +#define AM_REG_GPIO_INT0STAT_GPIO24_M 0x01000000 +#define AM_REG_GPIO_INT0STAT_GPIO24(n) (((uint32_t)(n) << 24) & 0x01000000) + +// GPIO23 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO23_S 23 +#define AM_REG_GPIO_INT0STAT_GPIO23_M 0x00800000 +#define AM_REG_GPIO_INT0STAT_GPIO23(n) (((uint32_t)(n) << 23) & 0x00800000) + +// GPIO22 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO22_S 22 +#define AM_REG_GPIO_INT0STAT_GPIO22_M 0x00400000 +#define AM_REG_GPIO_INT0STAT_GPIO22(n) (((uint32_t)(n) << 22) & 0x00400000) + +// GPIO21 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO21_S 21 +#define AM_REG_GPIO_INT0STAT_GPIO21_M 0x00200000 +#define AM_REG_GPIO_INT0STAT_GPIO21(n) (((uint32_t)(n) << 21) & 0x00200000) + +// GPIO20 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO20_S 20 +#define AM_REG_GPIO_INT0STAT_GPIO20_M 0x00100000 +#define AM_REG_GPIO_INT0STAT_GPIO20(n) (((uint32_t)(n) << 20) & 0x00100000) + +// GPIO19 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO19_S 19 +#define AM_REG_GPIO_INT0STAT_GPIO19_M 0x00080000 +#define AM_REG_GPIO_INT0STAT_GPIO19(n) (((uint32_t)(n) << 19) & 0x00080000) + +// GPIO18interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO18_S 18 +#define AM_REG_GPIO_INT0STAT_GPIO18_M 0x00040000 +#define AM_REG_GPIO_INT0STAT_GPIO18(n) (((uint32_t)(n) << 18) & 0x00040000) + +// GPIO17 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO17_S 17 +#define AM_REG_GPIO_INT0STAT_GPIO17_M 0x00020000 +#define AM_REG_GPIO_INT0STAT_GPIO17(n) (((uint32_t)(n) << 17) & 0x00020000) + +// GPIO16 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO16_S 16 +#define AM_REG_GPIO_INT0STAT_GPIO16_M 0x00010000 +#define AM_REG_GPIO_INT0STAT_GPIO16(n) (((uint32_t)(n) << 16) & 0x00010000) + +// GPIO15 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO15_S 15 +#define AM_REG_GPIO_INT0STAT_GPIO15_M 0x00008000 +#define AM_REG_GPIO_INT0STAT_GPIO15(n) (((uint32_t)(n) << 15) & 0x00008000) + +// GPIO14 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO14_S 14 +#define AM_REG_GPIO_INT0STAT_GPIO14_M 0x00004000 +#define AM_REG_GPIO_INT0STAT_GPIO14(n) (((uint32_t)(n) << 14) & 0x00004000) + +// GPIO13 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO13_S 13 +#define AM_REG_GPIO_INT0STAT_GPIO13_M 0x00002000 +#define AM_REG_GPIO_INT0STAT_GPIO13(n) (((uint32_t)(n) << 13) & 0x00002000) + +// GPIO12 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO12_S 12 +#define AM_REG_GPIO_INT0STAT_GPIO12_M 0x00001000 +#define AM_REG_GPIO_INT0STAT_GPIO12(n) (((uint32_t)(n) << 12) & 0x00001000) + +// GPIO11 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO11_S 11 +#define AM_REG_GPIO_INT0STAT_GPIO11_M 0x00000800 +#define AM_REG_GPIO_INT0STAT_GPIO11(n) (((uint32_t)(n) << 11) & 0x00000800) + +// GPIO10 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO10_S 10 +#define AM_REG_GPIO_INT0STAT_GPIO10_M 0x00000400 +#define AM_REG_GPIO_INT0STAT_GPIO10(n) (((uint32_t)(n) << 10) & 0x00000400) + +// GPIO9 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO9_S 9 +#define AM_REG_GPIO_INT0STAT_GPIO9_M 0x00000200 +#define AM_REG_GPIO_INT0STAT_GPIO9(n) (((uint32_t)(n) << 9) & 0x00000200) + +// GPIO8 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO8_S 8 +#define AM_REG_GPIO_INT0STAT_GPIO8_M 0x00000100 +#define AM_REG_GPIO_INT0STAT_GPIO8(n) (((uint32_t)(n) << 8) & 0x00000100) + +// GPIO7 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO7_S 7 +#define AM_REG_GPIO_INT0STAT_GPIO7_M 0x00000080 +#define AM_REG_GPIO_INT0STAT_GPIO7(n) (((uint32_t)(n) << 7) & 0x00000080) + +// GPIO6 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO6_S 6 +#define AM_REG_GPIO_INT0STAT_GPIO6_M 0x00000040 +#define AM_REG_GPIO_INT0STAT_GPIO6(n) (((uint32_t)(n) << 6) & 0x00000040) + +// GPIO5 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO5_S 5 +#define AM_REG_GPIO_INT0STAT_GPIO5_M 0x00000020 +#define AM_REG_GPIO_INT0STAT_GPIO5(n) (((uint32_t)(n) << 5) & 0x00000020) + +// GPIO4 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO4_S 4 +#define AM_REG_GPIO_INT0STAT_GPIO4_M 0x00000010 +#define AM_REG_GPIO_INT0STAT_GPIO4(n) (((uint32_t)(n) << 4) & 0x00000010) + +// GPIO3 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO3_S 3 +#define AM_REG_GPIO_INT0STAT_GPIO3_M 0x00000008 +#define AM_REG_GPIO_INT0STAT_GPIO3(n) (((uint32_t)(n) << 3) & 0x00000008) + +// GPIO2 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO2_S 2 +#define AM_REG_GPIO_INT0STAT_GPIO2_M 0x00000004 +#define AM_REG_GPIO_INT0STAT_GPIO2(n) (((uint32_t)(n) << 2) & 0x00000004) + +// GPIO1 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO1_S 1 +#define AM_REG_GPIO_INT0STAT_GPIO1_M 0x00000002 +#define AM_REG_GPIO_INT0STAT_GPIO1(n) (((uint32_t)(n) << 1) & 0x00000002) + +// GPIO0 interrupt. +#define AM_REG_GPIO_INT0STAT_GPIO0_S 0 +#define AM_REG_GPIO_INT0STAT_GPIO0_M 0x00000001 +#define AM_REG_GPIO_INT0STAT_GPIO0(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_INT0CLR - GPIO Interrupt Registers 31-0: Clear +// +//***************************************************************************** +// GPIO31 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO31_S 31 +#define AM_REG_GPIO_INT0CLR_GPIO31_M 0x80000000 +#define AM_REG_GPIO_INT0CLR_GPIO31(n) (((uint32_t)(n) << 31) & 0x80000000) + +// GPIO30 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO30_S 30 +#define AM_REG_GPIO_INT0CLR_GPIO30_M 0x40000000 +#define AM_REG_GPIO_INT0CLR_GPIO30(n) (((uint32_t)(n) << 30) & 0x40000000) + +// GPIO29 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO29_S 29 +#define AM_REG_GPIO_INT0CLR_GPIO29_M 0x20000000 +#define AM_REG_GPIO_INT0CLR_GPIO29(n) (((uint32_t)(n) << 29) & 0x20000000) + +// GPIO28 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO28_S 28 +#define AM_REG_GPIO_INT0CLR_GPIO28_M 0x10000000 +#define AM_REG_GPIO_INT0CLR_GPIO28(n) (((uint32_t)(n) << 28) & 0x10000000) + +// GPIO27 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO27_S 27 +#define AM_REG_GPIO_INT0CLR_GPIO27_M 0x08000000 +#define AM_REG_GPIO_INT0CLR_GPIO27(n) (((uint32_t)(n) << 27) & 0x08000000) + +// GPIO26 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO26_S 26 +#define AM_REG_GPIO_INT0CLR_GPIO26_M 0x04000000 +#define AM_REG_GPIO_INT0CLR_GPIO26(n) (((uint32_t)(n) << 26) & 0x04000000) + +// GPIO25 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO25_S 25 +#define AM_REG_GPIO_INT0CLR_GPIO25_M 0x02000000 +#define AM_REG_GPIO_INT0CLR_GPIO25(n) (((uint32_t)(n) << 25) & 0x02000000) + +// GPIO24 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO24_S 24 +#define AM_REG_GPIO_INT0CLR_GPIO24_M 0x01000000 +#define AM_REG_GPIO_INT0CLR_GPIO24(n) (((uint32_t)(n) << 24) & 0x01000000) + +// GPIO23 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO23_S 23 +#define AM_REG_GPIO_INT0CLR_GPIO23_M 0x00800000 +#define AM_REG_GPIO_INT0CLR_GPIO23(n) (((uint32_t)(n) << 23) & 0x00800000) + +// GPIO22 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO22_S 22 +#define AM_REG_GPIO_INT0CLR_GPIO22_M 0x00400000 +#define AM_REG_GPIO_INT0CLR_GPIO22(n) (((uint32_t)(n) << 22) & 0x00400000) + +// GPIO21 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO21_S 21 +#define AM_REG_GPIO_INT0CLR_GPIO21_M 0x00200000 +#define AM_REG_GPIO_INT0CLR_GPIO21(n) (((uint32_t)(n) << 21) & 0x00200000) + +// GPIO20 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO20_S 20 +#define AM_REG_GPIO_INT0CLR_GPIO20_M 0x00100000 +#define AM_REG_GPIO_INT0CLR_GPIO20(n) (((uint32_t)(n) << 20) & 0x00100000) + +// GPIO19 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO19_S 19 +#define AM_REG_GPIO_INT0CLR_GPIO19_M 0x00080000 +#define AM_REG_GPIO_INT0CLR_GPIO19(n) (((uint32_t)(n) << 19) & 0x00080000) + +// GPIO18interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO18_S 18 +#define AM_REG_GPIO_INT0CLR_GPIO18_M 0x00040000 +#define AM_REG_GPIO_INT0CLR_GPIO18(n) (((uint32_t)(n) << 18) & 0x00040000) + +// GPIO17 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO17_S 17 +#define AM_REG_GPIO_INT0CLR_GPIO17_M 0x00020000 +#define AM_REG_GPIO_INT0CLR_GPIO17(n) (((uint32_t)(n) << 17) & 0x00020000) + +// GPIO16 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO16_S 16 +#define AM_REG_GPIO_INT0CLR_GPIO16_M 0x00010000 +#define AM_REG_GPIO_INT0CLR_GPIO16(n) (((uint32_t)(n) << 16) & 0x00010000) + +// GPIO15 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO15_S 15 +#define AM_REG_GPIO_INT0CLR_GPIO15_M 0x00008000 +#define AM_REG_GPIO_INT0CLR_GPIO15(n) (((uint32_t)(n) << 15) & 0x00008000) + +// GPIO14 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO14_S 14 +#define AM_REG_GPIO_INT0CLR_GPIO14_M 0x00004000 +#define AM_REG_GPIO_INT0CLR_GPIO14(n) (((uint32_t)(n) << 14) & 0x00004000) + +// GPIO13 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO13_S 13 +#define AM_REG_GPIO_INT0CLR_GPIO13_M 0x00002000 +#define AM_REG_GPIO_INT0CLR_GPIO13(n) (((uint32_t)(n) << 13) & 0x00002000) + +// GPIO12 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO12_S 12 +#define AM_REG_GPIO_INT0CLR_GPIO12_M 0x00001000 +#define AM_REG_GPIO_INT0CLR_GPIO12(n) (((uint32_t)(n) << 12) & 0x00001000) + +// GPIO11 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO11_S 11 +#define AM_REG_GPIO_INT0CLR_GPIO11_M 0x00000800 +#define AM_REG_GPIO_INT0CLR_GPIO11(n) (((uint32_t)(n) << 11) & 0x00000800) + +// GPIO10 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO10_S 10 +#define AM_REG_GPIO_INT0CLR_GPIO10_M 0x00000400 +#define AM_REG_GPIO_INT0CLR_GPIO10(n) (((uint32_t)(n) << 10) & 0x00000400) + +// GPIO9 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO9_S 9 +#define AM_REG_GPIO_INT0CLR_GPIO9_M 0x00000200 +#define AM_REG_GPIO_INT0CLR_GPIO9(n) (((uint32_t)(n) << 9) & 0x00000200) + +// GPIO8 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO8_S 8 +#define AM_REG_GPIO_INT0CLR_GPIO8_M 0x00000100 +#define AM_REG_GPIO_INT0CLR_GPIO8(n) (((uint32_t)(n) << 8) & 0x00000100) + +// GPIO7 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO7_S 7 +#define AM_REG_GPIO_INT0CLR_GPIO7_M 0x00000080 +#define AM_REG_GPIO_INT0CLR_GPIO7(n) (((uint32_t)(n) << 7) & 0x00000080) + +// GPIO6 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO6_S 6 +#define AM_REG_GPIO_INT0CLR_GPIO6_M 0x00000040 +#define AM_REG_GPIO_INT0CLR_GPIO6(n) (((uint32_t)(n) << 6) & 0x00000040) + +// GPIO5 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO5_S 5 +#define AM_REG_GPIO_INT0CLR_GPIO5_M 0x00000020 +#define AM_REG_GPIO_INT0CLR_GPIO5(n) (((uint32_t)(n) << 5) & 0x00000020) + +// GPIO4 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO4_S 4 +#define AM_REG_GPIO_INT0CLR_GPIO4_M 0x00000010 +#define AM_REG_GPIO_INT0CLR_GPIO4(n) (((uint32_t)(n) << 4) & 0x00000010) + +// GPIO3 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO3_S 3 +#define AM_REG_GPIO_INT0CLR_GPIO3_M 0x00000008 +#define AM_REG_GPIO_INT0CLR_GPIO3(n) (((uint32_t)(n) << 3) & 0x00000008) + +// GPIO2 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO2_S 2 +#define AM_REG_GPIO_INT0CLR_GPIO2_M 0x00000004 +#define AM_REG_GPIO_INT0CLR_GPIO2(n) (((uint32_t)(n) << 2) & 0x00000004) + +// GPIO1 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO1_S 1 +#define AM_REG_GPIO_INT0CLR_GPIO1_M 0x00000002 +#define AM_REG_GPIO_INT0CLR_GPIO1(n) (((uint32_t)(n) << 1) & 0x00000002) + +// GPIO0 interrupt. +#define AM_REG_GPIO_INT0CLR_GPIO0_S 0 +#define AM_REG_GPIO_INT0CLR_GPIO0_M 0x00000001 +#define AM_REG_GPIO_INT0CLR_GPIO0(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_INT0SET - GPIO Interrupt Registers 31-0: Set +// +//***************************************************************************** +// GPIO31 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO31_S 31 +#define AM_REG_GPIO_INT0SET_GPIO31_M 0x80000000 +#define AM_REG_GPIO_INT0SET_GPIO31(n) (((uint32_t)(n) << 31) & 0x80000000) + +// GPIO30 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO30_S 30 +#define AM_REG_GPIO_INT0SET_GPIO30_M 0x40000000 +#define AM_REG_GPIO_INT0SET_GPIO30(n) (((uint32_t)(n) << 30) & 0x40000000) + +// GPIO29 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO29_S 29 +#define AM_REG_GPIO_INT0SET_GPIO29_M 0x20000000 +#define AM_REG_GPIO_INT0SET_GPIO29(n) (((uint32_t)(n) << 29) & 0x20000000) + +// GPIO28 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO28_S 28 +#define AM_REG_GPIO_INT0SET_GPIO28_M 0x10000000 +#define AM_REG_GPIO_INT0SET_GPIO28(n) (((uint32_t)(n) << 28) & 0x10000000) + +// GPIO27 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO27_S 27 +#define AM_REG_GPIO_INT0SET_GPIO27_M 0x08000000 +#define AM_REG_GPIO_INT0SET_GPIO27(n) (((uint32_t)(n) << 27) & 0x08000000) + +// GPIO26 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO26_S 26 +#define AM_REG_GPIO_INT0SET_GPIO26_M 0x04000000 +#define AM_REG_GPIO_INT0SET_GPIO26(n) (((uint32_t)(n) << 26) & 0x04000000) + +// GPIO25 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO25_S 25 +#define AM_REG_GPIO_INT0SET_GPIO25_M 0x02000000 +#define AM_REG_GPIO_INT0SET_GPIO25(n) (((uint32_t)(n) << 25) & 0x02000000) + +// GPIO24 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO24_S 24 +#define AM_REG_GPIO_INT0SET_GPIO24_M 0x01000000 +#define AM_REG_GPIO_INT0SET_GPIO24(n) (((uint32_t)(n) << 24) & 0x01000000) + +// GPIO23 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO23_S 23 +#define AM_REG_GPIO_INT0SET_GPIO23_M 0x00800000 +#define AM_REG_GPIO_INT0SET_GPIO23(n) (((uint32_t)(n) << 23) & 0x00800000) + +// GPIO22 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO22_S 22 +#define AM_REG_GPIO_INT0SET_GPIO22_M 0x00400000 +#define AM_REG_GPIO_INT0SET_GPIO22(n) (((uint32_t)(n) << 22) & 0x00400000) + +// GPIO21 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO21_S 21 +#define AM_REG_GPIO_INT0SET_GPIO21_M 0x00200000 +#define AM_REG_GPIO_INT0SET_GPIO21(n) (((uint32_t)(n) << 21) & 0x00200000) + +// GPIO20 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO20_S 20 +#define AM_REG_GPIO_INT0SET_GPIO20_M 0x00100000 +#define AM_REG_GPIO_INT0SET_GPIO20(n) (((uint32_t)(n) << 20) & 0x00100000) + +// GPIO19 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO19_S 19 +#define AM_REG_GPIO_INT0SET_GPIO19_M 0x00080000 +#define AM_REG_GPIO_INT0SET_GPIO19(n) (((uint32_t)(n) << 19) & 0x00080000) + +// GPIO18interrupt. +#define AM_REG_GPIO_INT0SET_GPIO18_S 18 +#define AM_REG_GPIO_INT0SET_GPIO18_M 0x00040000 +#define AM_REG_GPIO_INT0SET_GPIO18(n) (((uint32_t)(n) << 18) & 0x00040000) + +// GPIO17 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO17_S 17 +#define AM_REG_GPIO_INT0SET_GPIO17_M 0x00020000 +#define AM_REG_GPIO_INT0SET_GPIO17(n) (((uint32_t)(n) << 17) & 0x00020000) + +// GPIO16 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO16_S 16 +#define AM_REG_GPIO_INT0SET_GPIO16_M 0x00010000 +#define AM_REG_GPIO_INT0SET_GPIO16(n) (((uint32_t)(n) << 16) & 0x00010000) + +// GPIO15 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO15_S 15 +#define AM_REG_GPIO_INT0SET_GPIO15_M 0x00008000 +#define AM_REG_GPIO_INT0SET_GPIO15(n) (((uint32_t)(n) << 15) & 0x00008000) + +// GPIO14 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO14_S 14 +#define AM_REG_GPIO_INT0SET_GPIO14_M 0x00004000 +#define AM_REG_GPIO_INT0SET_GPIO14(n) (((uint32_t)(n) << 14) & 0x00004000) + +// GPIO13 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO13_S 13 +#define AM_REG_GPIO_INT0SET_GPIO13_M 0x00002000 +#define AM_REG_GPIO_INT0SET_GPIO13(n) (((uint32_t)(n) << 13) & 0x00002000) + +// GPIO12 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO12_S 12 +#define AM_REG_GPIO_INT0SET_GPIO12_M 0x00001000 +#define AM_REG_GPIO_INT0SET_GPIO12(n) (((uint32_t)(n) << 12) & 0x00001000) + +// GPIO11 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO11_S 11 +#define AM_REG_GPIO_INT0SET_GPIO11_M 0x00000800 +#define AM_REG_GPIO_INT0SET_GPIO11(n) (((uint32_t)(n) << 11) & 0x00000800) + +// GPIO10 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO10_S 10 +#define AM_REG_GPIO_INT0SET_GPIO10_M 0x00000400 +#define AM_REG_GPIO_INT0SET_GPIO10(n) (((uint32_t)(n) << 10) & 0x00000400) + +// GPIO9 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO9_S 9 +#define AM_REG_GPIO_INT0SET_GPIO9_M 0x00000200 +#define AM_REG_GPIO_INT0SET_GPIO9(n) (((uint32_t)(n) << 9) & 0x00000200) + +// GPIO8 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO8_S 8 +#define AM_REG_GPIO_INT0SET_GPIO8_M 0x00000100 +#define AM_REG_GPIO_INT0SET_GPIO8(n) (((uint32_t)(n) << 8) & 0x00000100) + +// GPIO7 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO7_S 7 +#define AM_REG_GPIO_INT0SET_GPIO7_M 0x00000080 +#define AM_REG_GPIO_INT0SET_GPIO7(n) (((uint32_t)(n) << 7) & 0x00000080) + +// GPIO6 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO6_S 6 +#define AM_REG_GPIO_INT0SET_GPIO6_M 0x00000040 +#define AM_REG_GPIO_INT0SET_GPIO6(n) (((uint32_t)(n) << 6) & 0x00000040) + +// GPIO5 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO5_S 5 +#define AM_REG_GPIO_INT0SET_GPIO5_M 0x00000020 +#define AM_REG_GPIO_INT0SET_GPIO5(n) (((uint32_t)(n) << 5) & 0x00000020) + +// GPIO4 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO4_S 4 +#define AM_REG_GPIO_INT0SET_GPIO4_M 0x00000010 +#define AM_REG_GPIO_INT0SET_GPIO4(n) (((uint32_t)(n) << 4) & 0x00000010) + +// GPIO3 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO3_S 3 +#define AM_REG_GPIO_INT0SET_GPIO3_M 0x00000008 +#define AM_REG_GPIO_INT0SET_GPIO3(n) (((uint32_t)(n) << 3) & 0x00000008) + +// GPIO2 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO2_S 2 +#define AM_REG_GPIO_INT0SET_GPIO2_M 0x00000004 +#define AM_REG_GPIO_INT0SET_GPIO2(n) (((uint32_t)(n) << 2) & 0x00000004) + +// GPIO1 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO1_S 1 +#define AM_REG_GPIO_INT0SET_GPIO1_M 0x00000002 +#define AM_REG_GPIO_INT0SET_GPIO1(n) (((uint32_t)(n) << 1) & 0x00000002) + +// GPIO0 interrupt. +#define AM_REG_GPIO_INT0SET_GPIO0_S 0 +#define AM_REG_GPIO_INT0SET_GPIO0_M 0x00000001 +#define AM_REG_GPIO_INT0SET_GPIO0(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_INT1EN - GPIO Interrupt Registers 49-32: Enable +// +//***************************************************************************** +// GPIO49 interrupt. +#define AM_REG_GPIO_INT1EN_GPIO49_S 17 +#define AM_REG_GPIO_INT1EN_GPIO49_M 0x00020000 +#define AM_REG_GPIO_INT1EN_GPIO49(n) (((uint32_t)(n) << 17) & 0x00020000) + +// GPIO48 interrupt. +#define AM_REG_GPIO_INT1EN_GPIO48_S 16 +#define AM_REG_GPIO_INT1EN_GPIO48_M 0x00010000 +#define AM_REG_GPIO_INT1EN_GPIO48(n) (((uint32_t)(n) << 16) & 0x00010000) + +// GPIO47 interrupt. +#define AM_REG_GPIO_INT1EN_GPIO47_S 15 +#define AM_REG_GPIO_INT1EN_GPIO47_M 0x00008000 +#define AM_REG_GPIO_INT1EN_GPIO47(n) (((uint32_t)(n) << 15) & 0x00008000) + +// GPIO46 interrupt. +#define AM_REG_GPIO_INT1EN_GPIO46_S 14 +#define AM_REG_GPIO_INT1EN_GPIO46_M 0x00004000 +#define AM_REG_GPIO_INT1EN_GPIO46(n) (((uint32_t)(n) << 14) & 0x00004000) + +// GPIO45 interrupt. +#define AM_REG_GPIO_INT1EN_GPIO45_S 13 +#define AM_REG_GPIO_INT1EN_GPIO45_M 0x00002000 +#define AM_REG_GPIO_INT1EN_GPIO45(n) (((uint32_t)(n) << 13) & 0x00002000) + +// GPIO44 interrupt. +#define AM_REG_GPIO_INT1EN_GPIO44_S 12 +#define AM_REG_GPIO_INT1EN_GPIO44_M 0x00001000 +#define AM_REG_GPIO_INT1EN_GPIO44(n) (((uint32_t)(n) << 12) & 0x00001000) + +// GPIO43 interrupt. +#define AM_REG_GPIO_INT1EN_GPIO43_S 11 +#define AM_REG_GPIO_INT1EN_GPIO43_M 0x00000800 +#define AM_REG_GPIO_INT1EN_GPIO43(n) (((uint32_t)(n) << 11) & 0x00000800) + +// GPIO42 interrupt. +#define AM_REG_GPIO_INT1EN_GPIO42_S 10 +#define AM_REG_GPIO_INT1EN_GPIO42_M 0x00000400 +#define AM_REG_GPIO_INT1EN_GPIO42(n) (((uint32_t)(n) << 10) & 0x00000400) + +// GPIO41 interrupt. +#define AM_REG_GPIO_INT1EN_GPIO41_S 9 +#define AM_REG_GPIO_INT1EN_GPIO41_M 0x00000200 +#define AM_REG_GPIO_INT1EN_GPIO41(n) (((uint32_t)(n) << 9) & 0x00000200) + +// GPIO40 interrupt. +#define AM_REG_GPIO_INT1EN_GPIO40_S 8 +#define AM_REG_GPIO_INT1EN_GPIO40_M 0x00000100 +#define AM_REG_GPIO_INT1EN_GPIO40(n) (((uint32_t)(n) << 8) & 0x00000100) + +// GPIO39 interrupt. +#define AM_REG_GPIO_INT1EN_GPIO39_S 7 +#define AM_REG_GPIO_INT1EN_GPIO39_M 0x00000080 +#define AM_REG_GPIO_INT1EN_GPIO39(n) (((uint32_t)(n) << 7) & 0x00000080) + +// GPIO38 interrupt. +#define AM_REG_GPIO_INT1EN_GPIO38_S 6 +#define AM_REG_GPIO_INT1EN_GPIO38_M 0x00000040 +#define AM_REG_GPIO_INT1EN_GPIO38(n) (((uint32_t)(n) << 6) & 0x00000040) + +// GPIO37 interrupt. +#define AM_REG_GPIO_INT1EN_GPIO37_S 5 +#define AM_REG_GPIO_INT1EN_GPIO37_M 0x00000020 +#define AM_REG_GPIO_INT1EN_GPIO37(n) (((uint32_t)(n) << 5) & 0x00000020) + +// GPIO36 interrupt. +#define AM_REG_GPIO_INT1EN_GPIO36_S 4 +#define AM_REG_GPIO_INT1EN_GPIO36_M 0x00000010 +#define AM_REG_GPIO_INT1EN_GPIO36(n) (((uint32_t)(n) << 4) & 0x00000010) + +// GPIO35 interrupt. +#define AM_REG_GPIO_INT1EN_GPIO35_S 3 +#define AM_REG_GPIO_INT1EN_GPIO35_M 0x00000008 +#define AM_REG_GPIO_INT1EN_GPIO35(n) (((uint32_t)(n) << 3) & 0x00000008) + +// GPIO34 interrupt. +#define AM_REG_GPIO_INT1EN_GPIO34_S 2 +#define AM_REG_GPIO_INT1EN_GPIO34_M 0x00000004 +#define AM_REG_GPIO_INT1EN_GPIO34(n) (((uint32_t)(n) << 2) & 0x00000004) + +// GPIO33 interrupt. +#define AM_REG_GPIO_INT1EN_GPIO33_S 1 +#define AM_REG_GPIO_INT1EN_GPIO33_M 0x00000002 +#define AM_REG_GPIO_INT1EN_GPIO33(n) (((uint32_t)(n) << 1) & 0x00000002) + +// GPIO32 interrupt. +#define AM_REG_GPIO_INT1EN_GPIO32_S 0 +#define AM_REG_GPIO_INT1EN_GPIO32_M 0x00000001 +#define AM_REG_GPIO_INT1EN_GPIO32(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_INT1STAT - GPIO Interrupt Registers 49-32: Status +// +//***************************************************************************** +// GPIO49 interrupt. +#define AM_REG_GPIO_INT1STAT_GPIO49_S 17 +#define AM_REG_GPIO_INT1STAT_GPIO49_M 0x00020000 +#define AM_REG_GPIO_INT1STAT_GPIO49(n) (((uint32_t)(n) << 17) & 0x00020000) + +// GPIO48 interrupt. +#define AM_REG_GPIO_INT1STAT_GPIO48_S 16 +#define AM_REG_GPIO_INT1STAT_GPIO48_M 0x00010000 +#define AM_REG_GPIO_INT1STAT_GPIO48(n) (((uint32_t)(n) << 16) & 0x00010000) + +// GPIO47 interrupt. +#define AM_REG_GPIO_INT1STAT_GPIO47_S 15 +#define AM_REG_GPIO_INT1STAT_GPIO47_M 0x00008000 +#define AM_REG_GPIO_INT1STAT_GPIO47(n) (((uint32_t)(n) << 15) & 0x00008000) + +// GPIO46 interrupt. +#define AM_REG_GPIO_INT1STAT_GPIO46_S 14 +#define AM_REG_GPIO_INT1STAT_GPIO46_M 0x00004000 +#define AM_REG_GPIO_INT1STAT_GPIO46(n) (((uint32_t)(n) << 14) & 0x00004000) + +// GPIO45 interrupt. +#define AM_REG_GPIO_INT1STAT_GPIO45_S 13 +#define AM_REG_GPIO_INT1STAT_GPIO45_M 0x00002000 +#define AM_REG_GPIO_INT1STAT_GPIO45(n) (((uint32_t)(n) << 13) & 0x00002000) + +// GPIO44 interrupt. +#define AM_REG_GPIO_INT1STAT_GPIO44_S 12 +#define AM_REG_GPIO_INT1STAT_GPIO44_M 0x00001000 +#define AM_REG_GPIO_INT1STAT_GPIO44(n) (((uint32_t)(n) << 12) & 0x00001000) + +// GPIO43 interrupt. +#define AM_REG_GPIO_INT1STAT_GPIO43_S 11 +#define AM_REG_GPIO_INT1STAT_GPIO43_M 0x00000800 +#define AM_REG_GPIO_INT1STAT_GPIO43(n) (((uint32_t)(n) << 11) & 0x00000800) + +// GPIO42 interrupt. +#define AM_REG_GPIO_INT1STAT_GPIO42_S 10 +#define AM_REG_GPIO_INT1STAT_GPIO42_M 0x00000400 +#define AM_REG_GPIO_INT1STAT_GPIO42(n) (((uint32_t)(n) << 10) & 0x00000400) + +// GPIO41 interrupt. +#define AM_REG_GPIO_INT1STAT_GPIO41_S 9 +#define AM_REG_GPIO_INT1STAT_GPIO41_M 0x00000200 +#define AM_REG_GPIO_INT1STAT_GPIO41(n) (((uint32_t)(n) << 9) & 0x00000200) + +// GPIO40 interrupt. +#define AM_REG_GPIO_INT1STAT_GPIO40_S 8 +#define AM_REG_GPIO_INT1STAT_GPIO40_M 0x00000100 +#define AM_REG_GPIO_INT1STAT_GPIO40(n) (((uint32_t)(n) << 8) & 0x00000100) + +// GPIO39 interrupt. +#define AM_REG_GPIO_INT1STAT_GPIO39_S 7 +#define AM_REG_GPIO_INT1STAT_GPIO39_M 0x00000080 +#define AM_REG_GPIO_INT1STAT_GPIO39(n) (((uint32_t)(n) << 7) & 0x00000080) + +// GPIO38 interrupt. +#define AM_REG_GPIO_INT1STAT_GPIO38_S 6 +#define AM_REG_GPIO_INT1STAT_GPIO38_M 0x00000040 +#define AM_REG_GPIO_INT1STAT_GPIO38(n) (((uint32_t)(n) << 6) & 0x00000040) + +// GPIO37 interrupt. +#define AM_REG_GPIO_INT1STAT_GPIO37_S 5 +#define AM_REG_GPIO_INT1STAT_GPIO37_M 0x00000020 +#define AM_REG_GPIO_INT1STAT_GPIO37(n) (((uint32_t)(n) << 5) & 0x00000020) + +// GPIO36 interrupt. +#define AM_REG_GPIO_INT1STAT_GPIO36_S 4 +#define AM_REG_GPIO_INT1STAT_GPIO36_M 0x00000010 +#define AM_REG_GPIO_INT1STAT_GPIO36(n) (((uint32_t)(n) << 4) & 0x00000010) + +// GPIO35 interrupt. +#define AM_REG_GPIO_INT1STAT_GPIO35_S 3 +#define AM_REG_GPIO_INT1STAT_GPIO35_M 0x00000008 +#define AM_REG_GPIO_INT1STAT_GPIO35(n) (((uint32_t)(n) << 3) & 0x00000008) + +// GPIO34 interrupt. +#define AM_REG_GPIO_INT1STAT_GPIO34_S 2 +#define AM_REG_GPIO_INT1STAT_GPIO34_M 0x00000004 +#define AM_REG_GPIO_INT1STAT_GPIO34(n) (((uint32_t)(n) << 2) & 0x00000004) + +// GPIO33 interrupt. +#define AM_REG_GPIO_INT1STAT_GPIO33_S 1 +#define AM_REG_GPIO_INT1STAT_GPIO33_M 0x00000002 +#define AM_REG_GPIO_INT1STAT_GPIO33(n) (((uint32_t)(n) << 1) & 0x00000002) + +// GPIO32 interrupt. +#define AM_REG_GPIO_INT1STAT_GPIO32_S 0 +#define AM_REG_GPIO_INT1STAT_GPIO32_M 0x00000001 +#define AM_REG_GPIO_INT1STAT_GPIO32(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_INT1CLR - GPIO Interrupt Registers 49-32: Clear +// +//***************************************************************************** +// GPIO49 interrupt. +#define AM_REG_GPIO_INT1CLR_GPIO49_S 17 +#define AM_REG_GPIO_INT1CLR_GPIO49_M 0x00020000 +#define AM_REG_GPIO_INT1CLR_GPIO49(n) (((uint32_t)(n) << 17) & 0x00020000) + +// GPIO48 interrupt. +#define AM_REG_GPIO_INT1CLR_GPIO48_S 16 +#define AM_REG_GPIO_INT1CLR_GPIO48_M 0x00010000 +#define AM_REG_GPIO_INT1CLR_GPIO48(n) (((uint32_t)(n) << 16) & 0x00010000) + +// GPIO47 interrupt. +#define AM_REG_GPIO_INT1CLR_GPIO47_S 15 +#define AM_REG_GPIO_INT1CLR_GPIO47_M 0x00008000 +#define AM_REG_GPIO_INT1CLR_GPIO47(n) (((uint32_t)(n) << 15) & 0x00008000) + +// GPIO46 interrupt. +#define AM_REG_GPIO_INT1CLR_GPIO46_S 14 +#define AM_REG_GPIO_INT1CLR_GPIO46_M 0x00004000 +#define AM_REG_GPIO_INT1CLR_GPIO46(n) (((uint32_t)(n) << 14) & 0x00004000) + +// GPIO45 interrupt. +#define AM_REG_GPIO_INT1CLR_GPIO45_S 13 +#define AM_REG_GPIO_INT1CLR_GPIO45_M 0x00002000 +#define AM_REG_GPIO_INT1CLR_GPIO45(n) (((uint32_t)(n) << 13) & 0x00002000) + +// GPIO44 interrupt. +#define AM_REG_GPIO_INT1CLR_GPIO44_S 12 +#define AM_REG_GPIO_INT1CLR_GPIO44_M 0x00001000 +#define AM_REG_GPIO_INT1CLR_GPIO44(n) (((uint32_t)(n) << 12) & 0x00001000) + +// GPIO43 interrupt. +#define AM_REG_GPIO_INT1CLR_GPIO43_S 11 +#define AM_REG_GPIO_INT1CLR_GPIO43_M 0x00000800 +#define AM_REG_GPIO_INT1CLR_GPIO43(n) (((uint32_t)(n) << 11) & 0x00000800) + +// GPIO42 interrupt. +#define AM_REG_GPIO_INT1CLR_GPIO42_S 10 +#define AM_REG_GPIO_INT1CLR_GPIO42_M 0x00000400 +#define AM_REG_GPIO_INT1CLR_GPIO42(n) (((uint32_t)(n) << 10) & 0x00000400) + +// GPIO41 interrupt. +#define AM_REG_GPIO_INT1CLR_GPIO41_S 9 +#define AM_REG_GPIO_INT1CLR_GPIO41_M 0x00000200 +#define AM_REG_GPIO_INT1CLR_GPIO41(n) (((uint32_t)(n) << 9) & 0x00000200) + +// GPIO40 interrupt. +#define AM_REG_GPIO_INT1CLR_GPIO40_S 8 +#define AM_REG_GPIO_INT1CLR_GPIO40_M 0x00000100 +#define AM_REG_GPIO_INT1CLR_GPIO40(n) (((uint32_t)(n) << 8) & 0x00000100) + +// GPIO39 interrupt. +#define AM_REG_GPIO_INT1CLR_GPIO39_S 7 +#define AM_REG_GPIO_INT1CLR_GPIO39_M 0x00000080 +#define AM_REG_GPIO_INT1CLR_GPIO39(n) (((uint32_t)(n) << 7) & 0x00000080) + +// GPIO38 interrupt. +#define AM_REG_GPIO_INT1CLR_GPIO38_S 6 +#define AM_REG_GPIO_INT1CLR_GPIO38_M 0x00000040 +#define AM_REG_GPIO_INT1CLR_GPIO38(n) (((uint32_t)(n) << 6) & 0x00000040) + +// GPIO37 interrupt. +#define AM_REG_GPIO_INT1CLR_GPIO37_S 5 +#define AM_REG_GPIO_INT1CLR_GPIO37_M 0x00000020 +#define AM_REG_GPIO_INT1CLR_GPIO37(n) (((uint32_t)(n) << 5) & 0x00000020) + +// GPIO36 interrupt. +#define AM_REG_GPIO_INT1CLR_GPIO36_S 4 +#define AM_REG_GPIO_INT1CLR_GPIO36_M 0x00000010 +#define AM_REG_GPIO_INT1CLR_GPIO36(n) (((uint32_t)(n) << 4) & 0x00000010) + +// GPIO35 interrupt. +#define AM_REG_GPIO_INT1CLR_GPIO35_S 3 +#define AM_REG_GPIO_INT1CLR_GPIO35_M 0x00000008 +#define AM_REG_GPIO_INT1CLR_GPIO35(n) (((uint32_t)(n) << 3) & 0x00000008) + +// GPIO34 interrupt. +#define AM_REG_GPIO_INT1CLR_GPIO34_S 2 +#define AM_REG_GPIO_INT1CLR_GPIO34_M 0x00000004 +#define AM_REG_GPIO_INT1CLR_GPIO34(n) (((uint32_t)(n) << 2) & 0x00000004) + +// GPIO33 interrupt. +#define AM_REG_GPIO_INT1CLR_GPIO33_S 1 +#define AM_REG_GPIO_INT1CLR_GPIO33_M 0x00000002 +#define AM_REG_GPIO_INT1CLR_GPIO33(n) (((uint32_t)(n) << 1) & 0x00000002) + +// GPIO32 interrupt. +#define AM_REG_GPIO_INT1CLR_GPIO32_S 0 +#define AM_REG_GPIO_INT1CLR_GPIO32_M 0x00000001 +#define AM_REG_GPIO_INT1CLR_GPIO32(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_INT1SET - GPIO Interrupt Registers 49-32: Set +// +//***************************************************************************** +// GPIO49 interrupt. +#define AM_REG_GPIO_INT1SET_GPIO49_S 17 +#define AM_REG_GPIO_INT1SET_GPIO49_M 0x00020000 +#define AM_REG_GPIO_INT1SET_GPIO49(n) (((uint32_t)(n) << 17) & 0x00020000) + +// GPIO48 interrupt. +#define AM_REG_GPIO_INT1SET_GPIO48_S 16 +#define AM_REG_GPIO_INT1SET_GPIO48_M 0x00010000 +#define AM_REG_GPIO_INT1SET_GPIO48(n) (((uint32_t)(n) << 16) & 0x00010000) + +// GPIO47 interrupt. +#define AM_REG_GPIO_INT1SET_GPIO47_S 15 +#define AM_REG_GPIO_INT1SET_GPIO47_M 0x00008000 +#define AM_REG_GPIO_INT1SET_GPIO47(n) (((uint32_t)(n) << 15) & 0x00008000) + +// GPIO46 interrupt. +#define AM_REG_GPIO_INT1SET_GPIO46_S 14 +#define AM_REG_GPIO_INT1SET_GPIO46_M 0x00004000 +#define AM_REG_GPIO_INT1SET_GPIO46(n) (((uint32_t)(n) << 14) & 0x00004000) + +// GPIO45 interrupt. +#define AM_REG_GPIO_INT1SET_GPIO45_S 13 +#define AM_REG_GPIO_INT1SET_GPIO45_M 0x00002000 +#define AM_REG_GPIO_INT1SET_GPIO45(n) (((uint32_t)(n) << 13) & 0x00002000) + +// GPIO44 interrupt. +#define AM_REG_GPIO_INT1SET_GPIO44_S 12 +#define AM_REG_GPIO_INT1SET_GPIO44_M 0x00001000 +#define AM_REG_GPIO_INT1SET_GPIO44(n) (((uint32_t)(n) << 12) & 0x00001000) + +// GPIO43 interrupt. +#define AM_REG_GPIO_INT1SET_GPIO43_S 11 +#define AM_REG_GPIO_INT1SET_GPIO43_M 0x00000800 +#define AM_REG_GPIO_INT1SET_GPIO43(n) (((uint32_t)(n) << 11) & 0x00000800) + +// GPIO42 interrupt. +#define AM_REG_GPIO_INT1SET_GPIO42_S 10 +#define AM_REG_GPIO_INT1SET_GPIO42_M 0x00000400 +#define AM_REG_GPIO_INT1SET_GPIO42(n) (((uint32_t)(n) << 10) & 0x00000400) + +// GPIO41 interrupt. +#define AM_REG_GPIO_INT1SET_GPIO41_S 9 +#define AM_REG_GPIO_INT1SET_GPIO41_M 0x00000200 +#define AM_REG_GPIO_INT1SET_GPIO41(n) (((uint32_t)(n) << 9) & 0x00000200) + +// GPIO40 interrupt. +#define AM_REG_GPIO_INT1SET_GPIO40_S 8 +#define AM_REG_GPIO_INT1SET_GPIO40_M 0x00000100 +#define AM_REG_GPIO_INT1SET_GPIO40(n) (((uint32_t)(n) << 8) & 0x00000100) + +// GPIO39 interrupt. +#define AM_REG_GPIO_INT1SET_GPIO39_S 7 +#define AM_REG_GPIO_INT1SET_GPIO39_M 0x00000080 +#define AM_REG_GPIO_INT1SET_GPIO39(n) (((uint32_t)(n) << 7) & 0x00000080) + +// GPIO38 interrupt. +#define AM_REG_GPIO_INT1SET_GPIO38_S 6 +#define AM_REG_GPIO_INT1SET_GPIO38_M 0x00000040 +#define AM_REG_GPIO_INT1SET_GPIO38(n) (((uint32_t)(n) << 6) & 0x00000040) + +// GPIO37 interrupt. +#define AM_REG_GPIO_INT1SET_GPIO37_S 5 +#define AM_REG_GPIO_INT1SET_GPIO37_M 0x00000020 +#define AM_REG_GPIO_INT1SET_GPIO37(n) (((uint32_t)(n) << 5) & 0x00000020) + +// GPIO36 interrupt. +#define AM_REG_GPIO_INT1SET_GPIO36_S 4 +#define AM_REG_GPIO_INT1SET_GPIO36_M 0x00000010 +#define AM_REG_GPIO_INT1SET_GPIO36(n) (((uint32_t)(n) << 4) & 0x00000010) + +// GPIO35 interrupt. +#define AM_REG_GPIO_INT1SET_GPIO35_S 3 +#define AM_REG_GPIO_INT1SET_GPIO35_M 0x00000008 +#define AM_REG_GPIO_INT1SET_GPIO35(n) (((uint32_t)(n) << 3) & 0x00000008) + +// GPIO34 interrupt. +#define AM_REG_GPIO_INT1SET_GPIO34_S 2 +#define AM_REG_GPIO_INT1SET_GPIO34_M 0x00000004 +#define AM_REG_GPIO_INT1SET_GPIO34(n) (((uint32_t)(n) << 2) & 0x00000004) + +// GPIO33 interrupt. +#define AM_REG_GPIO_INT1SET_GPIO33_S 1 +#define AM_REG_GPIO_INT1SET_GPIO33_M 0x00000002 +#define AM_REG_GPIO_INT1SET_GPIO33(n) (((uint32_t)(n) << 1) & 0x00000002) + +// GPIO32 interrupt. +#define AM_REG_GPIO_INT1SET_GPIO32_S 0 +#define AM_REG_GPIO_INT1SET_GPIO32_M 0x00000001 +#define AM_REG_GPIO_INT1SET_GPIO32(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_PADREGA - Pad Configuration Register A +// +//***************************************************************************** +// Pad 3 function select +#define AM_REG_GPIO_PADREGA_PAD3FNCSEL_S 27 +#define AM_REG_GPIO_PADREGA_PAD3FNCSEL_M 0x38000000 +#define AM_REG_GPIO_PADREGA_PAD3FNCSEL(n) (((uint32_t)(n) << 27) & 0x38000000) +#define AM_REG_GPIO_PADREGA_PAD3FNCSEL_UA0RTS 0x00000000 +#define AM_REG_GPIO_PADREGA_PAD3FNCSEL_SLnCE 0x08000000 +#define AM_REG_GPIO_PADREGA_PAD3FNCSEL_M1nCE4 0x10000000 +#define AM_REG_GPIO_PADREGA_PAD3FNCSEL_GPIO3 0x18000000 +#define AM_REG_GPIO_PADREGA_PAD3FNCSEL_MxnCELB 0x20000000 +#define AM_REG_GPIO_PADREGA_PAD3FNCSEL_M2nCE0 0x28000000 +#define AM_REG_GPIO_PADREGA_PAD3FNCSEL_TRIG1 0x30000000 +#define AM_REG_GPIO_PADREGA_PAD3FNCSEL_I2S_WCLK 0x38000000 + +// Pad 3 drive strength. +#define AM_REG_GPIO_PADREGA_PAD3STRNG_S 26 +#define AM_REG_GPIO_PADREGA_PAD3STRNG_M 0x04000000 +#define AM_REG_GPIO_PADREGA_PAD3STRNG(n) (((uint32_t)(n) << 26) & 0x04000000) +#define AM_REG_GPIO_PADREGA_PAD3STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGA_PAD3STRNG_HIGH 0x04000000 + +// Pad 3 input enable. +#define AM_REG_GPIO_PADREGA_PAD3INPEN_S 25 +#define AM_REG_GPIO_PADREGA_PAD3INPEN_M 0x02000000 +#define AM_REG_GPIO_PADREGA_PAD3INPEN(n) (((uint32_t)(n) << 25) & 0x02000000) +#define AM_REG_GPIO_PADREGA_PAD3INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGA_PAD3INPEN_EN 0x02000000 + +// Pad 3 pullup enable +#define AM_REG_GPIO_PADREGA_PAD3PULL_S 24 +#define AM_REG_GPIO_PADREGA_PAD3PULL_M 0x01000000 +#define AM_REG_GPIO_PADREGA_PAD3PULL(n) (((uint32_t)(n) << 24) & 0x01000000) +#define AM_REG_GPIO_PADREGA_PAD3PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGA_PAD3PULL_EN 0x01000000 + +// Pad 2 function select +#define AM_REG_GPIO_PADREGA_PAD2FNCSEL_S 19 +#define AM_REG_GPIO_PADREGA_PAD2FNCSEL_M 0x00380000 +#define AM_REG_GPIO_PADREGA_PAD2FNCSEL(n) (((uint32_t)(n) << 19) & 0x00380000) +#define AM_REG_GPIO_PADREGA_PAD2FNCSEL_SLWIR3 0x00000000 +#define AM_REG_GPIO_PADREGA_PAD2FNCSEL_SLMOSI 0x00080000 +#define AM_REG_GPIO_PADREGA_PAD2FNCSEL_UART0RX 0x00100000 +#define AM_REG_GPIO_PADREGA_PAD2FNCSEL_GPIO2 0x00180000 +#define AM_REG_GPIO_PADREGA_PAD2FNCSEL_MxMOSILB 0x00200000 +#define AM_REG_GPIO_PADREGA_PAD2FNCSEL_M2MOSI 0x00280000 +#define AM_REG_GPIO_PADREGA_PAD2FNCSEL_MxWIR3LB 0x00300000 +#define AM_REG_GPIO_PADREGA_PAD2FNCSEL_M2WIR3 0x00380000 + +// Pad 2 drive strength +#define AM_REG_GPIO_PADREGA_PAD2STRNG_S 18 +#define AM_REG_GPIO_PADREGA_PAD2STRNG_M 0x00040000 +#define AM_REG_GPIO_PADREGA_PAD2STRNG(n) (((uint32_t)(n) << 18) & 0x00040000) +#define AM_REG_GPIO_PADREGA_PAD2STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGA_PAD2STRNG_HIGH 0x00040000 + +// Pad 2 input enable +#define AM_REG_GPIO_PADREGA_PAD2INPEN_S 17 +#define AM_REG_GPIO_PADREGA_PAD2INPEN_M 0x00020000 +#define AM_REG_GPIO_PADREGA_PAD2INPEN(n) (((uint32_t)(n) << 17) & 0x00020000) +#define AM_REG_GPIO_PADREGA_PAD2INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGA_PAD2INPEN_EN 0x00020000 + +// Pad 2 pullup enable +#define AM_REG_GPIO_PADREGA_PAD2PULL_S 16 +#define AM_REG_GPIO_PADREGA_PAD2PULL_M 0x00010000 +#define AM_REG_GPIO_PADREGA_PAD2PULL(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_GPIO_PADREGA_PAD2PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGA_PAD2PULL_EN 0x00010000 + +// Pad 1 pullup resistor selection. +#define AM_REG_GPIO_PADREGA_PAD1RSEL_S 14 +#define AM_REG_GPIO_PADREGA_PAD1RSEL_M 0x0000C000 +#define AM_REG_GPIO_PADREGA_PAD1RSEL(n) (((uint32_t)(n) << 14) & 0x0000C000) +#define AM_REG_GPIO_PADREGA_PAD1RSEL_PULL1_5K 0x00000000 +#define AM_REG_GPIO_PADREGA_PAD1RSEL_PULL6K 0x00004000 +#define AM_REG_GPIO_PADREGA_PAD1RSEL_PULL12K 0x00008000 +#define AM_REG_GPIO_PADREGA_PAD1RSEL_PULL24K 0x0000C000 + +// Pad 1 function select +#define AM_REG_GPIO_PADREGA_PAD1FNCSEL_S 11 +#define AM_REG_GPIO_PADREGA_PAD1FNCSEL_M 0x00003800 +#define AM_REG_GPIO_PADREGA_PAD1FNCSEL(n) (((uint32_t)(n) << 11) & 0x00003800) +#define AM_REG_GPIO_PADREGA_PAD1FNCSEL_SLSDA 0x00000000 +#define AM_REG_GPIO_PADREGA_PAD1FNCSEL_SLMISO 0x00000800 +#define AM_REG_GPIO_PADREGA_PAD1FNCSEL_UART0TX 0x00001000 +#define AM_REG_GPIO_PADREGA_PAD1FNCSEL_GPIO1 0x00001800 +#define AM_REG_GPIO_PADREGA_PAD1FNCSEL_MxMISOLB 0x00002000 +#define AM_REG_GPIO_PADREGA_PAD1FNCSEL_M2MISO 0x00002800 +#define AM_REG_GPIO_PADREGA_PAD1FNCSEL_MxSDALB 0x00003000 +#define AM_REG_GPIO_PADREGA_PAD1FNCSEL_M2SDA 0x00003800 + +// Pad 1 drive strength +#define AM_REG_GPIO_PADREGA_PAD1STRNG_S 10 +#define AM_REG_GPIO_PADREGA_PAD1STRNG_M 0x00000400 +#define AM_REG_GPIO_PADREGA_PAD1STRNG(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_GPIO_PADREGA_PAD1STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGA_PAD1STRNG_HIGH 0x00000400 + +// Pad 1 input enable +#define AM_REG_GPIO_PADREGA_PAD1INPEN_S 9 +#define AM_REG_GPIO_PADREGA_PAD1INPEN_M 0x00000200 +#define AM_REG_GPIO_PADREGA_PAD1INPEN(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_GPIO_PADREGA_PAD1INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGA_PAD1INPEN_EN 0x00000200 + +// Pad 1 pullup enable +#define AM_REG_GPIO_PADREGA_PAD1PULL_S 8 +#define AM_REG_GPIO_PADREGA_PAD1PULL_M 0x00000100 +#define AM_REG_GPIO_PADREGA_PAD1PULL(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_PADREGA_PAD1PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGA_PAD1PULL_EN 0x00000100 + +// Pad 0 pullup resistor selection. +#define AM_REG_GPIO_PADREGA_PAD0RSEL_S 6 +#define AM_REG_GPIO_PADREGA_PAD0RSEL_M 0x000000C0 +#define AM_REG_GPIO_PADREGA_PAD0RSEL(n) (((uint32_t)(n) << 6) & 0x000000C0) +#define AM_REG_GPIO_PADREGA_PAD0RSEL_PULL1_5K 0x00000000 +#define AM_REG_GPIO_PADREGA_PAD0RSEL_PULL6K 0x00000040 +#define AM_REG_GPIO_PADREGA_PAD0RSEL_PULL12K 0x00000080 +#define AM_REG_GPIO_PADREGA_PAD0RSEL_PULL24K 0x000000C0 + +// Pad 0 function select +#define AM_REG_GPIO_PADREGA_PAD0FNCSEL_S 3 +#define AM_REG_GPIO_PADREGA_PAD0FNCSEL_M 0x00000038 +#define AM_REG_GPIO_PADREGA_PAD0FNCSEL(n) (((uint32_t)(n) << 3) & 0x00000038) +#define AM_REG_GPIO_PADREGA_PAD0FNCSEL_SLSCL 0x00000000 +#define AM_REG_GPIO_PADREGA_PAD0FNCSEL_SLSCK 0x00000008 +#define AM_REG_GPIO_PADREGA_PAD0FNCSEL_CLKOUT 0x00000010 +#define AM_REG_GPIO_PADREGA_PAD0FNCSEL_GPIO0 0x00000018 +#define AM_REG_GPIO_PADREGA_PAD0FNCSEL_MxSCKLB 0x00000020 +#define AM_REG_GPIO_PADREGA_PAD0FNCSEL_M2SCK 0x00000028 +#define AM_REG_GPIO_PADREGA_PAD0FNCSEL_MxSCLLB 0x00000030 +#define AM_REG_GPIO_PADREGA_PAD0FNCSEL_M2SCL 0x00000038 + +// Pad 0 drive strength +#define AM_REG_GPIO_PADREGA_PAD0STRNG_S 2 +#define AM_REG_GPIO_PADREGA_PAD0STRNG_M 0x00000004 +#define AM_REG_GPIO_PADREGA_PAD0STRNG(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_GPIO_PADREGA_PAD0STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGA_PAD0STRNG_HIGH 0x00000004 + +// Pad 0 input enable +#define AM_REG_GPIO_PADREGA_PAD0INPEN_S 1 +#define AM_REG_GPIO_PADREGA_PAD0INPEN_M 0x00000002 +#define AM_REG_GPIO_PADREGA_PAD0INPEN(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_GPIO_PADREGA_PAD0INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGA_PAD0INPEN_EN 0x00000002 + +// Pad 0 pullup enable +#define AM_REG_GPIO_PADREGA_PAD0PULL_S 0 +#define AM_REG_GPIO_PADREGA_PAD0PULL_M 0x00000001 +#define AM_REG_GPIO_PADREGA_PAD0PULL(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_PADREGA_PAD0PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGA_PAD0PULL_EN 0x00000001 + +//***************************************************************************** +// +// GPIO_PADREGB - Pad Configuration Register B +// +//***************************************************************************** +// Pad 7 function select +#define AM_REG_GPIO_PADREGB_PAD7FNCSEL_S 27 +#define AM_REG_GPIO_PADREGB_PAD7FNCSEL_M 0x38000000 +#define AM_REG_GPIO_PADREGB_PAD7FNCSEL(n) (((uint32_t)(n) << 27) & 0x38000000) +#define AM_REG_GPIO_PADREGB_PAD7FNCSEL_M0WIR3 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD7FNCSEL_M0MOSI 0x08000000 +#define AM_REG_GPIO_PADREGB_PAD7FNCSEL_CLKOUT 0x10000000 +#define AM_REG_GPIO_PADREGB_PAD7FNCSEL_GPIO7 0x18000000 +#define AM_REG_GPIO_PADREGB_PAD7FNCSEL_TRIG0 0x20000000 +#define AM_REG_GPIO_PADREGB_PAD7FNCSEL_UART0TX 0x28000000 +#define AM_REG_GPIO_PADREGB_PAD7FNCSEL_SLWIR3LB 0x30000000 +#define AM_REG_GPIO_PADREGB_PAD7FNCSEL_M1nCE1 0x38000000 + +// Pad 7 drive strentgh +#define AM_REG_GPIO_PADREGB_PAD7STRNG_S 26 +#define AM_REG_GPIO_PADREGB_PAD7STRNG_M 0x04000000 +#define AM_REG_GPIO_PADREGB_PAD7STRNG(n) (((uint32_t)(n) << 26) & 0x04000000) +#define AM_REG_GPIO_PADREGB_PAD7STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD7STRNG_HIGH 0x04000000 + +// Pad 7 input enable +#define AM_REG_GPIO_PADREGB_PAD7INPEN_S 25 +#define AM_REG_GPIO_PADREGB_PAD7INPEN_M 0x02000000 +#define AM_REG_GPIO_PADREGB_PAD7INPEN(n) (((uint32_t)(n) << 25) & 0x02000000) +#define AM_REG_GPIO_PADREGB_PAD7INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD7INPEN_EN 0x02000000 + +// Pad 7 pullup enable +#define AM_REG_GPIO_PADREGB_PAD7PULL_S 24 +#define AM_REG_GPIO_PADREGB_PAD7PULL_M 0x01000000 +#define AM_REG_GPIO_PADREGB_PAD7PULL(n) (((uint32_t)(n) << 24) & 0x01000000) +#define AM_REG_GPIO_PADREGB_PAD7PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD7PULL_EN 0x01000000 + +// Pad 6 pullup resistor selection. +#define AM_REG_GPIO_PADREGB_PAD6RSEL_S 22 +#define AM_REG_GPIO_PADREGB_PAD6RSEL_M 0x00C00000 +#define AM_REG_GPIO_PADREGB_PAD6RSEL(n) (((uint32_t)(n) << 22) & 0x00C00000) +#define AM_REG_GPIO_PADREGB_PAD6RSEL_PULL1_5K 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD6RSEL_PULL6K 0x00400000 +#define AM_REG_GPIO_PADREGB_PAD6RSEL_PULL12K 0x00800000 +#define AM_REG_GPIO_PADREGB_PAD6RSEL_PULL24K 0x00C00000 + +// Pad 6 function select +#define AM_REG_GPIO_PADREGB_PAD6FNCSEL_S 19 +#define AM_REG_GPIO_PADREGB_PAD6FNCSEL_M 0x00380000 +#define AM_REG_GPIO_PADREGB_PAD6FNCSEL(n) (((uint32_t)(n) << 19) & 0x00380000) +#define AM_REG_GPIO_PADREGB_PAD6FNCSEL_M0SDA 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD6FNCSEL_M0MISO 0x00080000 +#define AM_REG_GPIO_PADREGB_PAD6FNCSEL_UA0CTS 0x00100000 +#define AM_REG_GPIO_PADREGB_PAD6FNCSEL_GPIO6 0x00180000 +#define AM_REG_GPIO_PADREGB_PAD6FNCSEL_SLMISOLB 0x00200000 +#define AM_REG_GPIO_PADREGB_PAD6FNCSEL_M1nCE0 0x00280000 +#define AM_REG_GPIO_PADREGB_PAD6FNCSEL_SLSDALB 0x00300000 +#define AM_REG_GPIO_PADREGB_PAD6FNCSEL_I2S_DAT 0x00380000 + +// Pad 6 drive strength +#define AM_REG_GPIO_PADREGB_PAD6STRNG_S 18 +#define AM_REG_GPIO_PADREGB_PAD6STRNG_M 0x00040000 +#define AM_REG_GPIO_PADREGB_PAD6STRNG(n) (((uint32_t)(n) << 18) & 0x00040000) +#define AM_REG_GPIO_PADREGB_PAD6STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD6STRNG_HIGH 0x00040000 + +// Pad 6 input enable +#define AM_REG_GPIO_PADREGB_PAD6INPEN_S 17 +#define AM_REG_GPIO_PADREGB_PAD6INPEN_M 0x00020000 +#define AM_REG_GPIO_PADREGB_PAD6INPEN(n) (((uint32_t)(n) << 17) & 0x00020000) +#define AM_REG_GPIO_PADREGB_PAD6INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD6INPEN_EN 0x00020000 + +// Pad 6 pullup enable +#define AM_REG_GPIO_PADREGB_PAD6PULL_S 16 +#define AM_REG_GPIO_PADREGB_PAD6PULL_M 0x00010000 +#define AM_REG_GPIO_PADREGB_PAD6PULL(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_GPIO_PADREGB_PAD6PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD6PULL_EN 0x00010000 + +// Pad 5 pullup resistor selection. +#define AM_REG_GPIO_PADREGB_PAD5RSEL_S 14 +#define AM_REG_GPIO_PADREGB_PAD5RSEL_M 0x0000C000 +#define AM_REG_GPIO_PADREGB_PAD5RSEL(n) (((uint32_t)(n) << 14) & 0x0000C000) +#define AM_REG_GPIO_PADREGB_PAD5RSEL_PULL1_5K 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD5RSEL_PULL6K 0x00004000 +#define AM_REG_GPIO_PADREGB_PAD5RSEL_PULL12K 0x00008000 +#define AM_REG_GPIO_PADREGB_PAD5RSEL_PULL24K 0x0000C000 + +// Pad 5 function select +#define AM_REG_GPIO_PADREGB_PAD5FNCSEL_S 11 +#define AM_REG_GPIO_PADREGB_PAD5FNCSEL_M 0x00003800 +#define AM_REG_GPIO_PADREGB_PAD5FNCSEL(n) (((uint32_t)(n) << 11) & 0x00003800) +#define AM_REG_GPIO_PADREGB_PAD5FNCSEL_M0SCL 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD5FNCSEL_M0SCK 0x00000800 +#define AM_REG_GPIO_PADREGB_PAD5FNCSEL_UA0RTS 0x00001000 +#define AM_REG_GPIO_PADREGB_PAD5FNCSEL_GPIO5 0x00001800 +#define AM_REG_GPIO_PADREGB_PAD5FNCSEL_M0SCKLB 0x00002000 +#define AM_REG_GPIO_PADREGB_PAD5FNCSEL_EXTHFA 0x00002800 +#define AM_REG_GPIO_PADREGB_PAD5FNCSEL_M0SCLLB 0x00003000 +#define AM_REG_GPIO_PADREGB_PAD5FNCSEL_M1nCE2 0x00003800 + +// Pad 5 drive strength +#define AM_REG_GPIO_PADREGB_PAD5STRNG_S 10 +#define AM_REG_GPIO_PADREGB_PAD5STRNG_M 0x00000400 +#define AM_REG_GPIO_PADREGB_PAD5STRNG(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_GPIO_PADREGB_PAD5STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD5STRNG_HIGH 0x00000400 + +// Pad 5 input enable +#define AM_REG_GPIO_PADREGB_PAD5INPEN_S 9 +#define AM_REG_GPIO_PADREGB_PAD5INPEN_M 0x00000200 +#define AM_REG_GPIO_PADREGB_PAD5INPEN(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_GPIO_PADREGB_PAD5INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD5INPEN_EN 0x00000200 + +// Pad 5 pullup enable +#define AM_REG_GPIO_PADREGB_PAD5PULL_S 8 +#define AM_REG_GPIO_PADREGB_PAD5PULL_M 0x00000100 +#define AM_REG_GPIO_PADREGB_PAD5PULL(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_PADREGB_PAD5PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD5PULL_EN 0x00000100 + +// Pad 4 VSS power switch enable +#define AM_REG_GPIO_PADREGB_PAD4PWRDN_S 7 +#define AM_REG_GPIO_PADREGB_PAD4PWRDN_M 0x00000080 +#define AM_REG_GPIO_PADREGB_PAD4PWRDN(n) (((uint32_t)(n) << 7) & 0x00000080) +#define AM_REG_GPIO_PADREGB_PAD4PWRDN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD4PWRDN_EN 0x00000080 + +// Pad 4 function select +#define AM_REG_GPIO_PADREGB_PAD4FNCSEL_S 3 +#define AM_REG_GPIO_PADREGB_PAD4FNCSEL_M 0x00000038 +#define AM_REG_GPIO_PADREGB_PAD4FNCSEL(n) (((uint32_t)(n) << 3) & 0x00000038) +#define AM_REG_GPIO_PADREGB_PAD4FNCSEL_UA0CTS 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD4FNCSEL_SLINT 0x00000008 +#define AM_REG_GPIO_PADREGB_PAD4FNCSEL_M0nCE5 0x00000010 +#define AM_REG_GPIO_PADREGB_PAD4FNCSEL_GPIO4 0x00000018 +#define AM_REG_GPIO_PADREGB_PAD4FNCSEL_SLINTGP 0x00000020 +#define AM_REG_GPIO_PADREGB_PAD4FNCSEL_M2nCE5 0x00000028 +#define AM_REG_GPIO_PADREGB_PAD4FNCSEL_CLKOUT 0x00000030 +#define AM_REG_GPIO_PADREGB_PAD4FNCSEL_32khz_XT 0x00000038 + +// Pad 4 drive strength +#define AM_REG_GPIO_PADREGB_PAD4STRNG_S 2 +#define AM_REG_GPIO_PADREGB_PAD4STRNG_M 0x00000004 +#define AM_REG_GPIO_PADREGB_PAD4STRNG(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_GPIO_PADREGB_PAD4STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD4STRNG_HIGH 0x00000004 + +// Pad 4 input enable +#define AM_REG_GPIO_PADREGB_PAD4INPEN_S 1 +#define AM_REG_GPIO_PADREGB_PAD4INPEN_M 0x00000002 +#define AM_REG_GPIO_PADREGB_PAD4INPEN(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_GPIO_PADREGB_PAD4INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD4INPEN_EN 0x00000002 + +// Pad 4 pullup enable +#define AM_REG_GPIO_PADREGB_PAD4PULL_S 0 +#define AM_REG_GPIO_PADREGB_PAD4PULL_M 0x00000001 +#define AM_REG_GPIO_PADREGB_PAD4PULL(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_PADREGB_PAD4PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGB_PAD4PULL_EN 0x00000001 + +//***************************************************************************** +// +// GPIO_PADREGC - Pad Configuration Register C +// +//***************************************************************************** +// Pad 11 function select +#define AM_REG_GPIO_PADREGC_PAD11FNCSEL_S 27 +#define AM_REG_GPIO_PADREGC_PAD11FNCSEL_M 0x38000000 +#define AM_REG_GPIO_PADREGC_PAD11FNCSEL(n) (((uint32_t)(n) << 27) & 0x38000000) +#define AM_REG_GPIO_PADREGC_PAD11FNCSEL_ADCSE2 0x00000000 +#define AM_REG_GPIO_PADREGC_PAD11FNCSEL_M0nCE0 0x08000000 +#define AM_REG_GPIO_PADREGC_PAD11FNCSEL_CLKOUT 0x10000000 +#define AM_REG_GPIO_PADREGC_PAD11FNCSEL_GPIO11 0x18000000 +#define AM_REG_GPIO_PADREGC_PAD11FNCSEL_M2nCE7 0x20000000 +#define AM_REG_GPIO_PADREGC_PAD11FNCSEL_UA1CTS 0x28000000 +#define AM_REG_GPIO_PADREGC_PAD11FNCSEL_UART0RX 0x30000000 +#define AM_REG_GPIO_PADREGC_PAD11FNCSEL_PDM_DATA 0x38000000 + +// Pad 11 drive strentgh +#define AM_REG_GPIO_PADREGC_PAD11STRNG_S 26 +#define AM_REG_GPIO_PADREGC_PAD11STRNG_M 0x04000000 +#define AM_REG_GPIO_PADREGC_PAD11STRNG(n) (((uint32_t)(n) << 26) & 0x04000000) +#define AM_REG_GPIO_PADREGC_PAD11STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGC_PAD11STRNG_HIGH 0x04000000 + +// Pad 11 input enable +#define AM_REG_GPIO_PADREGC_PAD11INPEN_S 25 +#define AM_REG_GPIO_PADREGC_PAD11INPEN_M 0x02000000 +#define AM_REG_GPIO_PADREGC_PAD11INPEN(n) (((uint32_t)(n) << 25) & 0x02000000) +#define AM_REG_GPIO_PADREGC_PAD11INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGC_PAD11INPEN_EN 0x02000000 + +// Pad 11 pullup enable +#define AM_REG_GPIO_PADREGC_PAD11PULL_S 24 +#define AM_REG_GPIO_PADREGC_PAD11PULL_M 0x01000000 +#define AM_REG_GPIO_PADREGC_PAD11PULL(n) (((uint32_t)(n) << 24) & 0x01000000) +#define AM_REG_GPIO_PADREGC_PAD11PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGC_PAD11PULL_EN 0x01000000 + +// Pad 10 function select +#define AM_REG_GPIO_PADREGC_PAD10FNCSEL_S 19 +#define AM_REG_GPIO_PADREGC_PAD10FNCSEL_M 0x00380000 +#define AM_REG_GPIO_PADREGC_PAD10FNCSEL(n) (((uint32_t)(n) << 19) & 0x00380000) +#define AM_REG_GPIO_PADREGC_PAD10FNCSEL_M1WIR3 0x00000000 +#define AM_REG_GPIO_PADREGC_PAD10FNCSEL_M1MOSI 0x00080000 +#define AM_REG_GPIO_PADREGC_PAD10FNCSEL_M0nCE6 0x00100000 +#define AM_REG_GPIO_PADREGC_PAD10FNCSEL_GPIO10 0x00180000 +#define AM_REG_GPIO_PADREGC_PAD10FNCSEL_M2nCE6 0x00200000 +#define AM_REG_GPIO_PADREGC_PAD10FNCSEL_UA1RTS 0x00280000 +#define AM_REG_GPIO_PADREGC_PAD10FNCSEL_M4nCE4 0x00300000 +#define AM_REG_GPIO_PADREGC_PAD10FNCSEL_SLWIR3LB 0x00380000 + +// Pad 10 drive strength +#define AM_REG_GPIO_PADREGC_PAD10STRNG_S 18 +#define AM_REG_GPIO_PADREGC_PAD10STRNG_M 0x00040000 +#define AM_REG_GPIO_PADREGC_PAD10STRNG(n) (((uint32_t)(n) << 18) & 0x00040000) +#define AM_REG_GPIO_PADREGC_PAD10STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGC_PAD10STRNG_HIGH 0x00040000 + +// Pad 10 input enable +#define AM_REG_GPIO_PADREGC_PAD10INPEN_S 17 +#define AM_REG_GPIO_PADREGC_PAD10INPEN_M 0x00020000 +#define AM_REG_GPIO_PADREGC_PAD10INPEN(n) (((uint32_t)(n) << 17) & 0x00020000) +#define AM_REG_GPIO_PADREGC_PAD10INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGC_PAD10INPEN_EN 0x00020000 + +// Pad 10 pullup enable +#define AM_REG_GPIO_PADREGC_PAD10PULL_S 16 +#define AM_REG_GPIO_PADREGC_PAD10PULL_M 0x00010000 +#define AM_REG_GPIO_PADREGC_PAD10PULL(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_GPIO_PADREGC_PAD10PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGC_PAD10PULL_EN 0x00010000 + +// Pad 9 pullup resistor selection +#define AM_REG_GPIO_PADREGC_PAD9RSEL_S 14 +#define AM_REG_GPIO_PADREGC_PAD9RSEL_M 0x0000C000 +#define AM_REG_GPIO_PADREGC_PAD9RSEL(n) (((uint32_t)(n) << 14) & 0x0000C000) +#define AM_REG_GPIO_PADREGC_PAD9RSEL_PULL1_5K 0x00000000 +#define AM_REG_GPIO_PADREGC_PAD9RSEL_PULL6K 0x00004000 +#define AM_REG_GPIO_PADREGC_PAD9RSEL_PULL12K 0x00008000 +#define AM_REG_GPIO_PADREGC_PAD9RSEL_PULL24K 0x0000C000 + +// Pad 9 function select +#define AM_REG_GPIO_PADREGC_PAD9FNCSEL_S 11 +#define AM_REG_GPIO_PADREGC_PAD9FNCSEL_M 0x00003800 +#define AM_REG_GPIO_PADREGC_PAD9FNCSEL(n) (((uint32_t)(n) << 11) & 0x00003800) +#define AM_REG_GPIO_PADREGC_PAD9FNCSEL_M1SDA 0x00000000 +#define AM_REG_GPIO_PADREGC_PAD9FNCSEL_M1MISO 0x00000800 +#define AM_REG_GPIO_PADREGC_PAD9FNCSEL_M0nCE5 0x00001000 +#define AM_REG_GPIO_PADREGC_PAD9FNCSEL_GPIO9 0x00001800 +#define AM_REG_GPIO_PADREGC_PAD9FNCSEL_M4nCE5 0x00002000 +#define AM_REG_GPIO_PADREGC_PAD9FNCSEL_SLMISOLB 0x00002800 +#define AM_REG_GPIO_PADREGC_PAD9FNCSEL_UART1RX 0x00003000 +#define AM_REG_GPIO_PADREGC_PAD9FNCSEL_SLSDALB 0x00003800 + +// Pad 9 drive strength +#define AM_REG_GPIO_PADREGC_PAD9STRNG_S 10 +#define AM_REG_GPIO_PADREGC_PAD9STRNG_M 0x00000400 +#define AM_REG_GPIO_PADREGC_PAD9STRNG(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_GPIO_PADREGC_PAD9STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGC_PAD9STRNG_HIGH 0x00000400 + +// Pad 9 input enable +#define AM_REG_GPIO_PADREGC_PAD9INPEN_S 9 +#define AM_REG_GPIO_PADREGC_PAD9INPEN_M 0x00000200 +#define AM_REG_GPIO_PADREGC_PAD9INPEN(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_GPIO_PADREGC_PAD9INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGC_PAD9INPEN_EN 0x00000200 + +// Pad 9 pullup enable +#define AM_REG_GPIO_PADREGC_PAD9PULL_S 8 +#define AM_REG_GPIO_PADREGC_PAD9PULL_M 0x00000100 +#define AM_REG_GPIO_PADREGC_PAD9PULL(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_PADREGC_PAD9PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGC_PAD9PULL_EN 0x00000100 + +// Pad 8 pullup resistor selection. +#define AM_REG_GPIO_PADREGC_PAD8RSEL_S 6 +#define AM_REG_GPIO_PADREGC_PAD8RSEL_M 0x000000C0 +#define AM_REG_GPIO_PADREGC_PAD8RSEL(n) (((uint32_t)(n) << 6) & 0x000000C0) +#define AM_REG_GPIO_PADREGC_PAD8RSEL_PULL1_5K 0x00000000 +#define AM_REG_GPIO_PADREGC_PAD8RSEL_PULL6K 0x00000040 +#define AM_REG_GPIO_PADREGC_PAD8RSEL_PULL12K 0x00000080 +#define AM_REG_GPIO_PADREGC_PAD8RSEL_PULL24K 0x000000C0 + +// Pad 8 function select +#define AM_REG_GPIO_PADREGC_PAD8FNCSEL_S 3 +#define AM_REG_GPIO_PADREGC_PAD8FNCSEL_M 0x00000038 +#define AM_REG_GPIO_PADREGC_PAD8FNCSEL(n) (((uint32_t)(n) << 3) & 0x00000038) +#define AM_REG_GPIO_PADREGC_PAD8FNCSEL_M1SCL 0x00000000 +#define AM_REG_GPIO_PADREGC_PAD8FNCSEL_M1SCK 0x00000008 +#define AM_REG_GPIO_PADREGC_PAD8FNCSEL_M0nCE4 0x00000010 +#define AM_REG_GPIO_PADREGC_PAD8FNCSEL_GPIO8 0x00000018 +#define AM_REG_GPIO_PADREGC_PAD8FNCSEL_M2nCE4 0x00000020 +#define AM_REG_GPIO_PADREGC_PAD8FNCSEL_M1SCKLB 0x00000028 +#define AM_REG_GPIO_PADREGC_PAD8FNCSEL_UART1TX 0x00000030 +#define AM_REG_GPIO_PADREGC_PAD8FNCSEL_M1SCLLB 0x00000038 + +// Pad 8 drive strength +#define AM_REG_GPIO_PADREGC_PAD8STRNG_S 2 +#define AM_REG_GPIO_PADREGC_PAD8STRNG_M 0x00000004 +#define AM_REG_GPIO_PADREGC_PAD8STRNG(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_GPIO_PADREGC_PAD8STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGC_PAD8STRNG_HIGH 0x00000004 + +// Pad 8 input enable +#define AM_REG_GPIO_PADREGC_PAD8INPEN_S 1 +#define AM_REG_GPIO_PADREGC_PAD8INPEN_M 0x00000002 +#define AM_REG_GPIO_PADREGC_PAD8INPEN(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_GPIO_PADREGC_PAD8INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGC_PAD8INPEN_EN 0x00000002 + +// Pad 8 pullup enable +#define AM_REG_GPIO_PADREGC_PAD8PULL_S 0 +#define AM_REG_GPIO_PADREGC_PAD8PULL_M 0x00000001 +#define AM_REG_GPIO_PADREGC_PAD8PULL(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_PADREGC_PAD8PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGC_PAD8PULL_EN 0x00000001 + +//***************************************************************************** +// +// GPIO_PADREGD - Pad Configuration Register D +// +//***************************************************************************** +// Pad 15 function select +#define AM_REG_GPIO_PADREGD_PAD15FNCSEL_S 27 +#define AM_REG_GPIO_PADREGD_PAD15FNCSEL_M 0x38000000 +#define AM_REG_GPIO_PADREGD_PAD15FNCSEL(n) (((uint32_t)(n) << 27) & 0x38000000) +#define AM_REG_GPIO_PADREGD_PAD15FNCSEL_ADCD1N 0x00000000 +#define AM_REG_GPIO_PADREGD_PAD15FNCSEL_M1nCE3 0x08000000 +#define AM_REG_GPIO_PADREGD_PAD15FNCSEL_UART1RX 0x10000000 +#define AM_REG_GPIO_PADREGD_PAD15FNCSEL_GPIO15 0x18000000 +#define AM_REG_GPIO_PADREGD_PAD15FNCSEL_M2nCE2 0x20000000 +#define AM_REG_GPIO_PADREGD_PAD15FNCSEL_EXTXT 0x28000000 +#define AM_REG_GPIO_PADREGD_PAD15FNCSEL_SWDIO 0x30000000 +#define AM_REG_GPIO_PADREGD_PAD15FNCSEL_SWO 0x38000000 + +// Pad 15 drive strentgh +#define AM_REG_GPIO_PADREGD_PAD15STRNG_S 26 +#define AM_REG_GPIO_PADREGD_PAD15STRNG_M 0x04000000 +#define AM_REG_GPIO_PADREGD_PAD15STRNG(n) (((uint32_t)(n) << 26) & 0x04000000) +#define AM_REG_GPIO_PADREGD_PAD15STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGD_PAD15STRNG_HIGH 0x04000000 + +// Pad 15 input enable +#define AM_REG_GPIO_PADREGD_PAD15INPEN_S 25 +#define AM_REG_GPIO_PADREGD_PAD15INPEN_M 0x02000000 +#define AM_REG_GPIO_PADREGD_PAD15INPEN(n) (((uint32_t)(n) << 25) & 0x02000000) +#define AM_REG_GPIO_PADREGD_PAD15INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGD_PAD15INPEN_EN 0x02000000 + +// Pad 15 pullup enable +#define AM_REG_GPIO_PADREGD_PAD15PULL_S 24 +#define AM_REG_GPIO_PADREGD_PAD15PULL_M 0x01000000 +#define AM_REG_GPIO_PADREGD_PAD15PULL(n) (((uint32_t)(n) << 24) & 0x01000000) +#define AM_REG_GPIO_PADREGD_PAD15PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGD_PAD15PULL_EN 0x01000000 + +// Pad 14 function select +#define AM_REG_GPIO_PADREGD_PAD14FNCSEL_S 19 +#define AM_REG_GPIO_PADREGD_PAD14FNCSEL_M 0x00380000 +#define AM_REG_GPIO_PADREGD_PAD14FNCSEL(n) (((uint32_t)(n) << 19) & 0x00380000) +#define AM_REG_GPIO_PADREGD_PAD14FNCSEL_ADCD1P 0x00000000 +#define AM_REG_GPIO_PADREGD_PAD14FNCSEL_M1nCE2 0x00080000 +#define AM_REG_GPIO_PADREGD_PAD14FNCSEL_UART1TX 0x00100000 +#define AM_REG_GPIO_PADREGD_PAD14FNCSEL_GPIO14 0x00180000 +#define AM_REG_GPIO_PADREGD_PAD14FNCSEL_M2nCE1 0x00200000 +#define AM_REG_GPIO_PADREGD_PAD14FNCSEL_EXTHFS 0x00280000 +#define AM_REG_GPIO_PADREGD_PAD14FNCSEL_SWDCK 0x00300000 +#define AM_REG_GPIO_PADREGD_PAD14FNCSEL_32khz_XT 0x00380000 + +// Pad 14 drive strength +#define AM_REG_GPIO_PADREGD_PAD14STRNG_S 18 +#define AM_REG_GPIO_PADREGD_PAD14STRNG_M 0x00040000 +#define AM_REG_GPIO_PADREGD_PAD14STRNG(n) (((uint32_t)(n) << 18) & 0x00040000) +#define AM_REG_GPIO_PADREGD_PAD14STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGD_PAD14STRNG_HIGH 0x00040000 + +// Pad 14 input enable +#define AM_REG_GPIO_PADREGD_PAD14INPEN_S 17 +#define AM_REG_GPIO_PADREGD_PAD14INPEN_M 0x00020000 +#define AM_REG_GPIO_PADREGD_PAD14INPEN(n) (((uint32_t)(n) << 17) & 0x00020000) +#define AM_REG_GPIO_PADREGD_PAD14INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGD_PAD14INPEN_EN 0x00020000 + +// Pad 14 pullup enable +#define AM_REG_GPIO_PADREGD_PAD14PULL_S 16 +#define AM_REG_GPIO_PADREGD_PAD14PULL_M 0x00010000 +#define AM_REG_GPIO_PADREGD_PAD14PULL(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_GPIO_PADREGD_PAD14PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGD_PAD14PULL_EN 0x00010000 + +// Pad 13 function select +#define AM_REG_GPIO_PADREGD_PAD13FNCSEL_S 11 +#define AM_REG_GPIO_PADREGD_PAD13FNCSEL_M 0x00003800 +#define AM_REG_GPIO_PADREGD_PAD13FNCSEL(n) (((uint32_t)(n) << 11) & 0x00003800) +#define AM_REG_GPIO_PADREGD_PAD13FNCSEL_ADCD0PSE8 0x00000000 +#define AM_REG_GPIO_PADREGD_PAD13FNCSEL_M1nCE1 0x00000800 +#define AM_REG_GPIO_PADREGD_PAD13FNCSEL_TCTB0 0x00001000 +#define AM_REG_GPIO_PADREGD_PAD13FNCSEL_GPIO13 0x00001800 +#define AM_REG_GPIO_PADREGD_PAD13FNCSEL_M2nCE3 0x00002000 +#define AM_REG_GPIO_PADREGD_PAD13FNCSEL_EXTHFB 0x00002800 +#define AM_REG_GPIO_PADREGD_PAD13FNCSEL_UA0RTS 0x00003000 +#define AM_REG_GPIO_PADREGD_PAD13FNCSEL_UART1RX 0x00003800 + +// Pad 13 drive strength +#define AM_REG_GPIO_PADREGD_PAD13STRNG_S 10 +#define AM_REG_GPIO_PADREGD_PAD13STRNG_M 0x00000400 +#define AM_REG_GPIO_PADREGD_PAD13STRNG(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_GPIO_PADREGD_PAD13STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGD_PAD13STRNG_HIGH 0x00000400 + +// Pad 13 input enable +#define AM_REG_GPIO_PADREGD_PAD13INPEN_S 9 +#define AM_REG_GPIO_PADREGD_PAD13INPEN_M 0x00000200 +#define AM_REG_GPIO_PADREGD_PAD13INPEN(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_GPIO_PADREGD_PAD13INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGD_PAD13INPEN_EN 0x00000200 + +// Pad 13 pullup enable +#define AM_REG_GPIO_PADREGD_PAD13PULL_S 8 +#define AM_REG_GPIO_PADREGD_PAD13PULL_M 0x00000100 +#define AM_REG_GPIO_PADREGD_PAD13PULL(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_PADREGD_PAD13PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGD_PAD13PULL_EN 0x00000100 + +// Pad 12 function select +#define AM_REG_GPIO_PADREGD_PAD12FNCSEL_S 3 +#define AM_REG_GPIO_PADREGD_PAD12FNCSEL_M 0x00000038 +#define AM_REG_GPIO_PADREGD_PAD12FNCSEL(n) (((uint32_t)(n) << 3) & 0x00000038) +#define AM_REG_GPIO_PADREGD_PAD12FNCSEL_ADCD0NSE9 0x00000000 +#define AM_REG_GPIO_PADREGD_PAD12FNCSEL_M1nCE0 0x00000008 +#define AM_REG_GPIO_PADREGD_PAD12FNCSEL_TCTA0 0x00000010 +#define AM_REG_GPIO_PADREGD_PAD12FNCSEL_GPIO12 0x00000018 +#define AM_REG_GPIO_PADREGD_PAD12FNCSEL_CLKOUT 0x00000020 +#define AM_REG_GPIO_PADREGD_PAD12FNCSEL_PDM_CLK 0x00000028 +#define AM_REG_GPIO_PADREGD_PAD12FNCSEL_UA0CTS 0x00000030 +#define AM_REG_GPIO_PADREGD_PAD12FNCSEL_UART1TX 0x00000038 + +// Pad 12 drive strength +#define AM_REG_GPIO_PADREGD_PAD12STRNG_S 2 +#define AM_REG_GPIO_PADREGD_PAD12STRNG_M 0x00000004 +#define AM_REG_GPIO_PADREGD_PAD12STRNG(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_GPIO_PADREGD_PAD12STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGD_PAD12STRNG_HIGH 0x00000004 + +// Pad 12 input enable +#define AM_REG_GPIO_PADREGD_PAD12INPEN_S 1 +#define AM_REG_GPIO_PADREGD_PAD12INPEN_M 0x00000002 +#define AM_REG_GPIO_PADREGD_PAD12INPEN(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_GPIO_PADREGD_PAD12INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGD_PAD12INPEN_EN 0x00000002 + +// Pad 12 pullup enable +#define AM_REG_GPIO_PADREGD_PAD12PULL_S 0 +#define AM_REG_GPIO_PADREGD_PAD12PULL_M 0x00000001 +#define AM_REG_GPIO_PADREGD_PAD12PULL(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_PADREGD_PAD12PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGD_PAD12PULL_EN 0x00000001 + +//***************************************************************************** +// +// GPIO_PADREGE - Pad Configuration Register E +// +//***************************************************************************** +// Pad 19 function select +#define AM_REG_GPIO_PADREGE_PAD19FNCSEL_S 27 +#define AM_REG_GPIO_PADREGE_PAD19FNCSEL_M 0x38000000 +#define AM_REG_GPIO_PADREGE_PAD19FNCSEL(n) (((uint32_t)(n) << 27) & 0x38000000) +#define AM_REG_GPIO_PADREGE_PAD19FNCSEL_CMPRF0 0x00000000 +#define AM_REG_GPIO_PADREGE_PAD19FNCSEL_M0nCE3 0x08000000 +#define AM_REG_GPIO_PADREGE_PAD19FNCSEL_TCTB1 0x10000000 +#define AM_REG_GPIO_PADREGE_PAD19FNCSEL_GPIO19 0x18000000 +#define AM_REG_GPIO_PADREGE_PAD19FNCSEL_TCTA1 0x20000000 +#define AM_REG_GPIO_PADREGE_PAD19FNCSEL_ANATEST1 0x28000000 +#define AM_REG_GPIO_PADREGE_PAD19FNCSEL_UART1RX 0x30000000 +#define AM_REG_GPIO_PADREGE_PAD19FNCSEL_I2S_BCLK 0x38000000 + +// Pad 19 drive strentgh +#define AM_REG_GPIO_PADREGE_PAD19STRNG_S 26 +#define AM_REG_GPIO_PADREGE_PAD19STRNG_M 0x04000000 +#define AM_REG_GPIO_PADREGE_PAD19STRNG(n) (((uint32_t)(n) << 26) & 0x04000000) +#define AM_REG_GPIO_PADREGE_PAD19STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGE_PAD19STRNG_HIGH 0x04000000 + +// Pad 19 input enable +#define AM_REG_GPIO_PADREGE_PAD19INPEN_S 25 +#define AM_REG_GPIO_PADREGE_PAD19INPEN_M 0x02000000 +#define AM_REG_GPIO_PADREGE_PAD19INPEN(n) (((uint32_t)(n) << 25) & 0x02000000) +#define AM_REG_GPIO_PADREGE_PAD19INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGE_PAD19INPEN_EN 0x02000000 + +// Pad 19 pullup enable +#define AM_REG_GPIO_PADREGE_PAD19PULL_S 24 +#define AM_REG_GPIO_PADREGE_PAD19PULL_M 0x01000000 +#define AM_REG_GPIO_PADREGE_PAD19PULL(n) (((uint32_t)(n) << 24) & 0x01000000) +#define AM_REG_GPIO_PADREGE_PAD19PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGE_PAD19PULL_EN 0x01000000 + +// Pad 18 function select +#define AM_REG_GPIO_PADREGE_PAD18FNCSEL_S 19 +#define AM_REG_GPIO_PADREGE_PAD18FNCSEL_M 0x00380000 +#define AM_REG_GPIO_PADREGE_PAD18FNCSEL(n) (((uint32_t)(n) << 19) & 0x00380000) +#define AM_REG_GPIO_PADREGE_PAD18FNCSEL_CMPIN1 0x00000000 +#define AM_REG_GPIO_PADREGE_PAD18FNCSEL_M0nCE2 0x00080000 +#define AM_REG_GPIO_PADREGE_PAD18FNCSEL_TCTA1 0x00100000 +#define AM_REG_GPIO_PADREGE_PAD18FNCSEL_GPIO18 0x00180000 +#define AM_REG_GPIO_PADREGE_PAD18FNCSEL_M4nCE1 0x00200000 +#define AM_REG_GPIO_PADREGE_PAD18FNCSEL_ANATEST2 0x00280000 +#define AM_REG_GPIO_PADREGE_PAD18FNCSEL_UART1TX 0x00300000 +#define AM_REG_GPIO_PADREGE_PAD18FNCSEL_32khz_XT 0x00380000 + +// Pad 18 drive strength +#define AM_REG_GPIO_PADREGE_PAD18STRNG_S 18 +#define AM_REG_GPIO_PADREGE_PAD18STRNG_M 0x00040000 +#define AM_REG_GPIO_PADREGE_PAD18STRNG(n) (((uint32_t)(n) << 18) & 0x00040000) +#define AM_REG_GPIO_PADREGE_PAD18STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGE_PAD18STRNG_HIGH 0x00040000 + +// Pad 18 input enable +#define AM_REG_GPIO_PADREGE_PAD18INPEN_S 17 +#define AM_REG_GPIO_PADREGE_PAD18INPEN_M 0x00020000 +#define AM_REG_GPIO_PADREGE_PAD18INPEN(n) (((uint32_t)(n) << 17) & 0x00020000) +#define AM_REG_GPIO_PADREGE_PAD18INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGE_PAD18INPEN_EN 0x00020000 + +// Pad 18 pullup enable +#define AM_REG_GPIO_PADREGE_PAD18PULL_S 16 +#define AM_REG_GPIO_PADREGE_PAD18PULL_M 0x00010000 +#define AM_REG_GPIO_PADREGE_PAD18PULL(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_GPIO_PADREGE_PAD18PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGE_PAD18PULL_EN 0x00010000 + +// Pad 17 function select +#define AM_REG_GPIO_PADREGE_PAD17FNCSEL_S 11 +#define AM_REG_GPIO_PADREGE_PAD17FNCSEL_M 0x00003800 +#define AM_REG_GPIO_PADREGE_PAD17FNCSEL(n) (((uint32_t)(n) << 11) & 0x00003800) +#define AM_REG_GPIO_PADREGE_PAD17FNCSEL_CMPRF1 0x00000000 +#define AM_REG_GPIO_PADREGE_PAD17FNCSEL_M0nCE1 0x00000800 +#define AM_REG_GPIO_PADREGE_PAD17FNCSEL_TRIG1 0x00001000 +#define AM_REG_GPIO_PADREGE_PAD17FNCSEL_GPIO17 0x00001800 +#define AM_REG_GPIO_PADREGE_PAD17FNCSEL_M4nCE3 0x00002000 +#define AM_REG_GPIO_PADREGE_PAD17FNCSEL_EXTLF 0x00002800 +#define AM_REG_GPIO_PADREGE_PAD17FNCSEL_UART0RX 0x00003000 +#define AM_REG_GPIO_PADREGE_PAD17FNCSEL_UA1CTS 0x00003800 + +// Pad 17 drive strength +#define AM_REG_GPIO_PADREGE_PAD17STRNG_S 10 +#define AM_REG_GPIO_PADREGE_PAD17STRNG_M 0x00000400 +#define AM_REG_GPIO_PADREGE_PAD17STRNG(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_GPIO_PADREGE_PAD17STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGE_PAD17STRNG_HIGH 0x00000400 + +// Pad 17 input enable +#define AM_REG_GPIO_PADREGE_PAD17INPEN_S 9 +#define AM_REG_GPIO_PADREGE_PAD17INPEN_M 0x00000200 +#define AM_REG_GPIO_PADREGE_PAD17INPEN(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_GPIO_PADREGE_PAD17INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGE_PAD17INPEN_EN 0x00000200 + +// Pad 17 pullup enable +#define AM_REG_GPIO_PADREGE_PAD17PULL_S 8 +#define AM_REG_GPIO_PADREGE_PAD17PULL_M 0x00000100 +#define AM_REG_GPIO_PADREGE_PAD17PULL(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_PADREGE_PAD17PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGE_PAD17PULL_EN 0x00000100 + +// Pad 16 function select +#define AM_REG_GPIO_PADREGE_PAD16FNCSEL_S 3 +#define AM_REG_GPIO_PADREGE_PAD16FNCSEL_M 0x00000038 +#define AM_REG_GPIO_PADREGE_PAD16FNCSEL(n) (((uint32_t)(n) << 3) & 0x00000038) +#define AM_REG_GPIO_PADREGE_PAD16FNCSEL_ADCSE0 0x00000000 +#define AM_REG_GPIO_PADREGE_PAD16FNCSEL_M0nCE4 0x00000008 +#define AM_REG_GPIO_PADREGE_PAD16FNCSEL_TRIG0 0x00000010 +#define AM_REG_GPIO_PADREGE_PAD16FNCSEL_GPIO16 0x00000018 +#define AM_REG_GPIO_PADREGE_PAD16FNCSEL_M2nCE3 0x00000020 +#define AM_REG_GPIO_PADREGE_PAD16FNCSEL_CMPIN0 0x00000028 +#define AM_REG_GPIO_PADREGE_PAD16FNCSEL_UART0TX 0x00000030 +#define AM_REG_GPIO_PADREGE_PAD16FNCSEL_UA1RTS 0x00000038 + +// Pad 16 drive strength +#define AM_REG_GPIO_PADREGE_PAD16STRNG_S 2 +#define AM_REG_GPIO_PADREGE_PAD16STRNG_M 0x00000004 +#define AM_REG_GPIO_PADREGE_PAD16STRNG(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_GPIO_PADREGE_PAD16STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGE_PAD16STRNG_HIGH 0x00000004 + +// Pad 16 input enable +#define AM_REG_GPIO_PADREGE_PAD16INPEN_S 1 +#define AM_REG_GPIO_PADREGE_PAD16INPEN_M 0x00000002 +#define AM_REG_GPIO_PADREGE_PAD16INPEN(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_GPIO_PADREGE_PAD16INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGE_PAD16INPEN_EN 0x00000002 + +// Pad 16 pullup enable +#define AM_REG_GPIO_PADREGE_PAD16PULL_S 0 +#define AM_REG_GPIO_PADREGE_PAD16PULL_M 0x00000001 +#define AM_REG_GPIO_PADREGE_PAD16PULL(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_PADREGE_PAD16PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGE_PAD16PULL_EN 0x00000001 + +//***************************************************************************** +// +// GPIO_PADREGF - Pad Configuration Register F +// +//***************************************************************************** +// Pad 23 function select +#define AM_REG_GPIO_PADREGF_PAD23FNCSEL_S 27 +#define AM_REG_GPIO_PADREGF_PAD23FNCSEL_M 0x38000000 +#define AM_REG_GPIO_PADREGF_PAD23FNCSEL(n) (((uint32_t)(n) << 27) & 0x38000000) +#define AM_REG_GPIO_PADREGF_PAD23FNCSEL_UART0RX 0x00000000 +#define AM_REG_GPIO_PADREGF_PAD23FNCSEL_M0nCE0 0x08000000 +#define AM_REG_GPIO_PADREGF_PAD23FNCSEL_TCTB3 0x10000000 +#define AM_REG_GPIO_PADREGF_PAD23FNCSEL_GPIO23 0x18000000 +#define AM_REG_GPIO_PADREGF_PAD23FNCSEL_PDM_DATA 0x20000000 +#define AM_REG_GPIO_PADREGF_PAD23FNCSEL_CMPOUT 0x28000000 +#define AM_REG_GPIO_PADREGF_PAD23FNCSEL_TCTB1 0x30000000 +#define AM_REG_GPIO_PADREGF_PAD23FNCSEL_UNDEF7 0x38000000 + +// Pad 23 drive strentgh +#define AM_REG_GPIO_PADREGF_PAD23STRNG_S 26 +#define AM_REG_GPIO_PADREGF_PAD23STRNG_M 0x04000000 +#define AM_REG_GPIO_PADREGF_PAD23STRNG(n) (((uint32_t)(n) << 26) & 0x04000000) +#define AM_REG_GPIO_PADREGF_PAD23STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGF_PAD23STRNG_HIGH 0x04000000 + +// Pad 23 input enable +#define AM_REG_GPIO_PADREGF_PAD23INPEN_S 25 +#define AM_REG_GPIO_PADREGF_PAD23INPEN_M 0x02000000 +#define AM_REG_GPIO_PADREGF_PAD23INPEN(n) (((uint32_t)(n) << 25) & 0x02000000) +#define AM_REG_GPIO_PADREGF_PAD23INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGF_PAD23INPEN_EN 0x02000000 + +// Pad 23 pullup enable +#define AM_REG_GPIO_PADREGF_PAD23PULL_S 24 +#define AM_REG_GPIO_PADREGF_PAD23PULL_M 0x01000000 +#define AM_REG_GPIO_PADREGF_PAD23PULL(n) (((uint32_t)(n) << 24) & 0x01000000) +#define AM_REG_GPIO_PADREGF_PAD23PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGF_PAD23PULL_EN 0x01000000 + +// Pad 22 upper power switch enable +#define AM_REG_GPIO_PADREGF_PAD22PWRUP_S 23 +#define AM_REG_GPIO_PADREGF_PAD22PWRUP_M 0x00800000 +#define AM_REG_GPIO_PADREGF_PAD22PWRUP(n) (((uint32_t)(n) << 23) & 0x00800000) +#define AM_REG_GPIO_PADREGF_PAD22PWRUP_DIS 0x00000000 +#define AM_REG_GPIO_PADREGF_PAD22PWRUP_EN 0x00800000 + +// Pad 22 function select +#define AM_REG_GPIO_PADREGF_PAD22FNCSEL_S 19 +#define AM_REG_GPIO_PADREGF_PAD22FNCSEL_M 0x00380000 +#define AM_REG_GPIO_PADREGF_PAD22FNCSEL(n) (((uint32_t)(n) << 19) & 0x00380000) +#define AM_REG_GPIO_PADREGF_PAD22FNCSEL_UART0TX 0x00000000 +#define AM_REG_GPIO_PADREGF_PAD22FNCSEL_M1nCE7 0x00080000 +#define AM_REG_GPIO_PADREGF_PAD22FNCSEL_TCTA3 0x00100000 +#define AM_REG_GPIO_PADREGF_PAD22FNCSEL_GPIO22 0x00180000 +#define AM_REG_GPIO_PADREGF_PAD22FNCSEL_PDM_CLK 0x00200000 +#define AM_REG_GPIO_PADREGF_PAD22FNCSEL_UNDEF5 0x00280000 +#define AM_REG_GPIO_PADREGF_PAD22FNCSEL_TCTB1 0x00300000 +#define AM_REG_GPIO_PADREGF_PAD22FNCSEL_SWO 0x00380000 + +// Pad 22 drive strength +#define AM_REG_GPIO_PADREGF_PAD22STRNG_S 18 +#define AM_REG_GPIO_PADREGF_PAD22STRNG_M 0x00040000 +#define AM_REG_GPIO_PADREGF_PAD22STRNG(n) (((uint32_t)(n) << 18) & 0x00040000) +#define AM_REG_GPIO_PADREGF_PAD22STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGF_PAD22STRNG_HIGH 0x00040000 + +// Pad 22 input enable +#define AM_REG_GPIO_PADREGF_PAD22INPEN_S 17 +#define AM_REG_GPIO_PADREGF_PAD22INPEN_M 0x00020000 +#define AM_REG_GPIO_PADREGF_PAD22INPEN(n) (((uint32_t)(n) << 17) & 0x00020000) +#define AM_REG_GPIO_PADREGF_PAD22INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGF_PAD22INPEN_EN 0x00020000 + +// Pad 22 pullup enable +#define AM_REG_GPIO_PADREGF_PAD22PULL_S 16 +#define AM_REG_GPIO_PADREGF_PAD22PULL_M 0x00010000 +#define AM_REG_GPIO_PADREGF_PAD22PULL(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_GPIO_PADREGF_PAD22PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGF_PAD22PULL_EN 0x00010000 + +// Pad 21 function select +#define AM_REG_GPIO_PADREGF_PAD21FNCSEL_S 11 +#define AM_REG_GPIO_PADREGF_PAD21FNCSEL_M 0x00003800 +#define AM_REG_GPIO_PADREGF_PAD21FNCSEL(n) (((uint32_t)(n) << 11) & 0x00003800) +#define AM_REG_GPIO_PADREGF_PAD21FNCSEL_SWDIO 0x00000000 +#define AM_REG_GPIO_PADREGF_PAD21FNCSEL_M1nCE6 0x00000800 +#define AM_REG_GPIO_PADREGF_PAD21FNCSEL_TCTB2 0x00001000 +#define AM_REG_GPIO_PADREGF_PAD21FNCSEL_GPIO21 0x00001800 +#define AM_REG_GPIO_PADREGF_PAD21FNCSEL_UART0RX 0x00002000 +#define AM_REG_GPIO_PADREGF_PAD21FNCSEL_UART1RX 0x00002800 +#define AM_REG_GPIO_PADREGF_PAD21FNCSEL_UNDEF6 0x00003000 +#define AM_REG_GPIO_PADREGF_PAD21FNCSEL_UNDEF7 0x00003800 + +// Pad 21 drive strength +#define AM_REG_GPIO_PADREGF_PAD21STRNG_S 10 +#define AM_REG_GPIO_PADREGF_PAD21STRNG_M 0x00000400 +#define AM_REG_GPIO_PADREGF_PAD21STRNG(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_GPIO_PADREGF_PAD21STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGF_PAD21STRNG_HIGH 0x00000400 + +// Pad 21 input enable +#define AM_REG_GPIO_PADREGF_PAD21INPEN_S 9 +#define AM_REG_GPIO_PADREGF_PAD21INPEN_M 0x00000200 +#define AM_REG_GPIO_PADREGF_PAD21INPEN(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_GPIO_PADREGF_PAD21INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGF_PAD21INPEN_EN 0x00000200 + +// Pad 21 pullup enable +#define AM_REG_GPIO_PADREGF_PAD21PULL_S 8 +#define AM_REG_GPIO_PADREGF_PAD21PULL_M 0x00000100 +#define AM_REG_GPIO_PADREGF_PAD21PULL(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_PADREGF_PAD21PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGF_PAD21PULL_EN 0x00000100 + +// Pad 20 function select +#define AM_REG_GPIO_PADREGF_PAD20FNCSEL_S 3 +#define AM_REG_GPIO_PADREGF_PAD20FNCSEL_M 0x00000038 +#define AM_REG_GPIO_PADREGF_PAD20FNCSEL(n) (((uint32_t)(n) << 3) & 0x00000038) +#define AM_REG_GPIO_PADREGF_PAD20FNCSEL_SWDCK 0x00000000 +#define AM_REG_GPIO_PADREGF_PAD20FNCSEL_M1nCE5 0x00000008 +#define AM_REG_GPIO_PADREGF_PAD20FNCSEL_TCTA2 0x00000010 +#define AM_REG_GPIO_PADREGF_PAD20FNCSEL_GPIO20 0x00000018 +#define AM_REG_GPIO_PADREGF_PAD20FNCSEL_UART0TX 0x00000020 +#define AM_REG_GPIO_PADREGF_PAD20FNCSEL_UART1TX 0x00000028 +#define AM_REG_GPIO_PADREGF_PAD20FNCSEL_UNDEF6 0x00000030 +#define AM_REG_GPIO_PADREGF_PAD20FNCSEL_UNDEF7 0x00000038 + +// Pad 20 drive strength +#define AM_REG_GPIO_PADREGF_PAD20STRNG_S 2 +#define AM_REG_GPIO_PADREGF_PAD20STRNG_M 0x00000004 +#define AM_REG_GPIO_PADREGF_PAD20STRNG(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_GPIO_PADREGF_PAD20STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGF_PAD20STRNG_HIGH 0x00000004 + +// Pad 20 input enable +#define AM_REG_GPIO_PADREGF_PAD20INPEN_S 1 +#define AM_REG_GPIO_PADREGF_PAD20INPEN_M 0x00000002 +#define AM_REG_GPIO_PADREGF_PAD20INPEN(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_GPIO_PADREGF_PAD20INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGF_PAD20INPEN_EN 0x00000002 + +// Pad 20 pulldown enable +#define AM_REG_GPIO_PADREGF_PAD20PULL_S 0 +#define AM_REG_GPIO_PADREGF_PAD20PULL_M 0x00000001 +#define AM_REG_GPIO_PADREGF_PAD20PULL(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_PADREGF_PAD20PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGF_PAD20PULL_EN 0x00000001 + +//***************************************************************************** +// +// GPIO_PADREGG - Pad Configuration Register G +// +//***************************************************************************** +// Pad 27 pullup resistor selection. +#define AM_REG_GPIO_PADREGG_PAD27RSEL_S 30 +#define AM_REG_GPIO_PADREGG_PAD27RSEL_M 0xC0000000 +#define AM_REG_GPIO_PADREGG_PAD27RSEL(n) (((uint32_t)(n) << 30) & 0xC0000000) +#define AM_REG_GPIO_PADREGG_PAD27RSEL_PULL1_5K 0x00000000 +#define AM_REG_GPIO_PADREGG_PAD27RSEL_PULL6K 0x40000000 +#define AM_REG_GPIO_PADREGG_PAD27RSEL_PULL12K 0x80000000 +#define AM_REG_GPIO_PADREGG_PAD27RSEL_PULL24K 0xC0000000 + +// Pad 27 function select +#define AM_REG_GPIO_PADREGG_PAD27FNCSEL_S 27 +#define AM_REG_GPIO_PADREGG_PAD27FNCSEL_M 0x38000000 +#define AM_REG_GPIO_PADREGG_PAD27FNCSEL(n) (((uint32_t)(n) << 27) & 0x38000000) +#define AM_REG_GPIO_PADREGG_PAD27FNCSEL_EXTHF 0x00000000 +#define AM_REG_GPIO_PADREGG_PAD27FNCSEL_M1nCE4 0x08000000 +#define AM_REG_GPIO_PADREGG_PAD27FNCSEL_TCTA1 0x10000000 +#define AM_REG_GPIO_PADREGG_PAD27FNCSEL_GPIO27 0x18000000 +#define AM_REG_GPIO_PADREGG_PAD27FNCSEL_M2SCL 0x20000000 +#define AM_REG_GPIO_PADREGG_PAD27FNCSEL_M2SCK 0x28000000 +#define AM_REG_GPIO_PADREGG_PAD27FNCSEL_M2SCKLB 0x30000000 +#define AM_REG_GPIO_PADREGG_PAD27FNCSEL_M2SCLLB 0x38000000 + +// Pad 27 drive strentgh +#define AM_REG_GPIO_PADREGG_PAD27STRNG_S 26 +#define AM_REG_GPIO_PADREGG_PAD27STRNG_M 0x04000000 +#define AM_REG_GPIO_PADREGG_PAD27STRNG(n) (((uint32_t)(n) << 26) & 0x04000000) +#define AM_REG_GPIO_PADREGG_PAD27STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGG_PAD27STRNG_HIGH 0x04000000 + +// Pad 27 input enable +#define AM_REG_GPIO_PADREGG_PAD27INPEN_S 25 +#define AM_REG_GPIO_PADREGG_PAD27INPEN_M 0x02000000 +#define AM_REG_GPIO_PADREGG_PAD27INPEN(n) (((uint32_t)(n) << 25) & 0x02000000) +#define AM_REG_GPIO_PADREGG_PAD27INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGG_PAD27INPEN_EN 0x02000000 + +// Pad 27 pullup enable +#define AM_REG_GPIO_PADREGG_PAD27PULL_S 24 +#define AM_REG_GPIO_PADREGG_PAD27PULL_M 0x01000000 +#define AM_REG_GPIO_PADREGG_PAD27PULL(n) (((uint32_t)(n) << 24) & 0x01000000) +#define AM_REG_GPIO_PADREGG_PAD27PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGG_PAD27PULL_EN 0x01000000 + +// Pad 26 function select +#define AM_REG_GPIO_PADREGG_PAD26FNCSEL_S 19 +#define AM_REG_GPIO_PADREGG_PAD26FNCSEL_M 0x00380000 +#define AM_REG_GPIO_PADREGG_PAD26FNCSEL(n) (((uint32_t)(n) << 19) & 0x00380000) +#define AM_REG_GPIO_PADREGG_PAD26FNCSEL_EXTLF 0x00000000 +#define AM_REG_GPIO_PADREGG_PAD26FNCSEL_M0nCE3 0x00080000 +#define AM_REG_GPIO_PADREGG_PAD26FNCSEL_TCTB0 0x00100000 +#define AM_REG_GPIO_PADREGG_PAD26FNCSEL_GPIO26 0x00180000 +#define AM_REG_GPIO_PADREGG_PAD26FNCSEL_M2nCE0 0x00200000 +#define AM_REG_GPIO_PADREGG_PAD26FNCSEL_TCTA1 0x00280000 +#define AM_REG_GPIO_PADREGG_PAD26FNCSEL_M5nCE1 0x00300000 +#define AM_REG_GPIO_PADREGG_PAD26FNCSEL_M3nCE0 0x00380000 + +// Pad 26 drive strength +#define AM_REG_GPIO_PADREGG_PAD26STRNG_S 18 +#define AM_REG_GPIO_PADREGG_PAD26STRNG_M 0x00040000 +#define AM_REG_GPIO_PADREGG_PAD26STRNG(n) (((uint32_t)(n) << 18) & 0x00040000) +#define AM_REG_GPIO_PADREGG_PAD26STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGG_PAD26STRNG_HIGH 0x00040000 + +// Pad 26 input enable +#define AM_REG_GPIO_PADREGG_PAD26INPEN_S 17 +#define AM_REG_GPIO_PADREGG_PAD26INPEN_M 0x00020000 +#define AM_REG_GPIO_PADREGG_PAD26INPEN(n) (((uint32_t)(n) << 17) & 0x00020000) +#define AM_REG_GPIO_PADREGG_PAD26INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGG_PAD26INPEN_EN 0x00020000 + +// Pad 26 pullup enable +#define AM_REG_GPIO_PADREGG_PAD26PULL_S 16 +#define AM_REG_GPIO_PADREGG_PAD26PULL_M 0x00010000 +#define AM_REG_GPIO_PADREGG_PAD26PULL(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_GPIO_PADREGG_PAD26PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGG_PAD26PULL_EN 0x00010000 + +// Pad 25 pullup resistor selection. +#define AM_REG_GPIO_PADREGG_PAD25RSEL_S 14 +#define AM_REG_GPIO_PADREGG_PAD25RSEL_M 0x0000C000 +#define AM_REG_GPIO_PADREGG_PAD25RSEL(n) (((uint32_t)(n) << 14) & 0x0000C000) +#define AM_REG_GPIO_PADREGG_PAD25RSEL_PULL1_5K 0x00000000 +#define AM_REG_GPIO_PADREGG_PAD25RSEL_PULL6K 0x00004000 +#define AM_REG_GPIO_PADREGG_PAD25RSEL_PULL12K 0x00008000 +#define AM_REG_GPIO_PADREGG_PAD25RSEL_PULL24K 0x0000C000 + +// Pad 25 function select +#define AM_REG_GPIO_PADREGG_PAD25FNCSEL_S 11 +#define AM_REG_GPIO_PADREGG_PAD25FNCSEL_M 0x00003800 +#define AM_REG_GPIO_PADREGG_PAD25FNCSEL(n) (((uint32_t)(n) << 11) & 0x00003800) +#define AM_REG_GPIO_PADREGG_PAD25FNCSEL_EXTXT 0x00000000 +#define AM_REG_GPIO_PADREGG_PAD25FNCSEL_M0nCE2 0x00000800 +#define AM_REG_GPIO_PADREGG_PAD25FNCSEL_TCTA0 0x00001000 +#define AM_REG_GPIO_PADREGG_PAD25FNCSEL_GPIO25 0x00001800 +#define AM_REG_GPIO_PADREGG_PAD25FNCSEL_M2SDA 0x00002000 +#define AM_REG_GPIO_PADREGG_PAD25FNCSEL_M2MISO 0x00002800 +#define AM_REG_GPIO_PADREGG_PAD25FNCSEL_SLMISOLB 0x00003000 +#define AM_REG_GPIO_PADREGG_PAD25FNCSEL_SLSDALB 0x00003800 + +// Pad 25 drive strength +#define AM_REG_GPIO_PADREGG_PAD25STRNG_S 10 +#define AM_REG_GPIO_PADREGG_PAD25STRNG_M 0x00000400 +#define AM_REG_GPIO_PADREGG_PAD25STRNG(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_GPIO_PADREGG_PAD25STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGG_PAD25STRNG_HIGH 0x00000400 + +// Pad 25 input enable +#define AM_REG_GPIO_PADREGG_PAD25INPEN_S 9 +#define AM_REG_GPIO_PADREGG_PAD25INPEN_M 0x00000200 +#define AM_REG_GPIO_PADREGG_PAD25INPEN(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_GPIO_PADREGG_PAD25INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGG_PAD25INPEN_EN 0x00000200 + +// Pad 25 pullup enable +#define AM_REG_GPIO_PADREGG_PAD25PULL_S 8 +#define AM_REG_GPIO_PADREGG_PAD25PULL_M 0x00000100 +#define AM_REG_GPIO_PADREGG_PAD25PULL(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_PADREGG_PAD25PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGG_PAD25PULL_EN 0x00000100 + +// Pad 24 function select +#define AM_REG_GPIO_PADREGG_PAD24FNCSEL_S 3 +#define AM_REG_GPIO_PADREGG_PAD24FNCSEL_M 0x00000038 +#define AM_REG_GPIO_PADREGG_PAD24FNCSEL(n) (((uint32_t)(n) << 3) & 0x00000038) +#define AM_REG_GPIO_PADREGG_PAD24FNCSEL_M2nCE1 0x00000000 +#define AM_REG_GPIO_PADREGG_PAD24FNCSEL_M0nCE1 0x00000008 +#define AM_REG_GPIO_PADREGG_PAD24FNCSEL_CLKOUT 0x00000010 +#define AM_REG_GPIO_PADREGG_PAD24FNCSEL_GPIO24 0x00000018 +#define AM_REG_GPIO_PADREGG_PAD24FNCSEL_M5nCE0 0x00000020 +#define AM_REG_GPIO_PADREGG_PAD24FNCSEL_TCTA1 0x00000028 +#define AM_REG_GPIO_PADREGG_PAD24FNCSEL_I2S_BCLK 0x00000030 +#define AM_REG_GPIO_PADREGG_PAD24FNCSEL_SWO 0x00000038 + +// Pad 24 drive strength +#define AM_REG_GPIO_PADREGG_PAD24STRNG_S 2 +#define AM_REG_GPIO_PADREGG_PAD24STRNG_M 0x00000004 +#define AM_REG_GPIO_PADREGG_PAD24STRNG(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_GPIO_PADREGG_PAD24STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGG_PAD24STRNG_HIGH 0x00000004 + +// Pad 24 input enable +#define AM_REG_GPIO_PADREGG_PAD24INPEN_S 1 +#define AM_REG_GPIO_PADREGG_PAD24INPEN_M 0x00000002 +#define AM_REG_GPIO_PADREGG_PAD24INPEN(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_GPIO_PADREGG_PAD24INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGG_PAD24INPEN_EN 0x00000002 + +// Pad 24 pullup enable +#define AM_REG_GPIO_PADREGG_PAD24PULL_S 0 +#define AM_REG_GPIO_PADREGG_PAD24PULL_M 0x00000001 +#define AM_REG_GPIO_PADREGG_PAD24PULL(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_PADREGG_PAD24PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGG_PAD24PULL_EN 0x00000001 + +//***************************************************************************** +// +// GPIO_PADREGH - Pad Configuration Register H +// +//***************************************************************************** +// Pad 31 function select +#define AM_REG_GPIO_PADREGH_PAD31FNCSEL_S 27 +#define AM_REG_GPIO_PADREGH_PAD31FNCSEL_M 0x38000000 +#define AM_REG_GPIO_PADREGH_PAD31FNCSEL(n) (((uint32_t)(n) << 27) & 0x38000000) +#define AM_REG_GPIO_PADREGH_PAD31FNCSEL_ADCSE3 0x00000000 +#define AM_REG_GPIO_PADREGH_PAD31FNCSEL_M0nCE4 0x08000000 +#define AM_REG_GPIO_PADREGH_PAD31FNCSEL_TCTA3 0x10000000 +#define AM_REG_GPIO_PADREGH_PAD31FNCSEL_GPIO31 0x18000000 +#define AM_REG_GPIO_PADREGH_PAD31FNCSEL_UART0RX 0x20000000 +#define AM_REG_GPIO_PADREGH_PAD31FNCSEL_TCTB1 0x28000000 +#define AM_REG_GPIO_PADREGH_PAD31FNCSEL_UNDEF6 0x30000000 +#define AM_REG_GPIO_PADREGH_PAD31FNCSEL_UNDEF7 0x38000000 + +// Pad 31 drive strentgh +#define AM_REG_GPIO_PADREGH_PAD31STRNG_S 26 +#define AM_REG_GPIO_PADREGH_PAD31STRNG_M 0x04000000 +#define AM_REG_GPIO_PADREGH_PAD31STRNG(n) (((uint32_t)(n) << 26) & 0x04000000) +#define AM_REG_GPIO_PADREGH_PAD31STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGH_PAD31STRNG_HIGH 0x04000000 + +// Pad 31 input enable +#define AM_REG_GPIO_PADREGH_PAD31INPEN_S 25 +#define AM_REG_GPIO_PADREGH_PAD31INPEN_M 0x02000000 +#define AM_REG_GPIO_PADREGH_PAD31INPEN(n) (((uint32_t)(n) << 25) & 0x02000000) +#define AM_REG_GPIO_PADREGH_PAD31INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGH_PAD31INPEN_EN 0x02000000 + +// Pad 31 pullup enable +#define AM_REG_GPIO_PADREGH_PAD31PULL_S 24 +#define AM_REG_GPIO_PADREGH_PAD31PULL_M 0x01000000 +#define AM_REG_GPIO_PADREGH_PAD31PULL(n) (((uint32_t)(n) << 24) & 0x01000000) +#define AM_REG_GPIO_PADREGH_PAD31PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGH_PAD31PULL_EN 0x01000000 + +// Pad 30 function select +#define AM_REG_GPIO_PADREGH_PAD30FNCSEL_S 19 +#define AM_REG_GPIO_PADREGH_PAD30FNCSEL_M 0x00380000 +#define AM_REG_GPIO_PADREGH_PAD30FNCSEL(n) (((uint32_t)(n) << 19) & 0x00380000) +#define AM_REG_GPIO_PADREGH_PAD30FNCSEL_UNDEF0 0x00000000 +#define AM_REG_GPIO_PADREGH_PAD30FNCSEL_M1nCE7 0x00080000 +#define AM_REG_GPIO_PADREGH_PAD30FNCSEL_TCTB2 0x00100000 +#define AM_REG_GPIO_PADREGH_PAD30FNCSEL_GPIO30 0x00180000 +#define AM_REG_GPIO_PADREGH_PAD30FNCSEL_UART0TX 0x00200000 +#define AM_REG_GPIO_PADREGH_PAD30FNCSEL_UA1RTS 0x00280000 +#define AM_REG_GPIO_PADREGH_PAD30FNCSEL_UNDEF6 0x00300000 +#define AM_REG_GPIO_PADREGH_PAD30FNCSEL_I2S_DAT 0x00380000 + +// Pad 30 drive strength +#define AM_REG_GPIO_PADREGH_PAD30STRNG_S 18 +#define AM_REG_GPIO_PADREGH_PAD30STRNG_M 0x00040000 +#define AM_REG_GPIO_PADREGH_PAD30STRNG(n) (((uint32_t)(n) << 18) & 0x00040000) +#define AM_REG_GPIO_PADREGH_PAD30STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGH_PAD30STRNG_HIGH 0x00040000 + +// Pad 30 input enable +#define AM_REG_GPIO_PADREGH_PAD30INPEN_S 17 +#define AM_REG_GPIO_PADREGH_PAD30INPEN_M 0x00020000 +#define AM_REG_GPIO_PADREGH_PAD30INPEN(n) (((uint32_t)(n) << 17) & 0x00020000) +#define AM_REG_GPIO_PADREGH_PAD30INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGH_PAD30INPEN_EN 0x00020000 + +// Pad 30 pullup enable +#define AM_REG_GPIO_PADREGH_PAD30PULL_S 16 +#define AM_REG_GPIO_PADREGH_PAD30PULL_M 0x00010000 +#define AM_REG_GPIO_PADREGH_PAD30PULL(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_GPIO_PADREGH_PAD30PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGH_PAD30PULL_EN 0x00010000 + +// Pad 29 function select +#define AM_REG_GPIO_PADREGH_PAD29FNCSEL_S 11 +#define AM_REG_GPIO_PADREGH_PAD29FNCSEL_M 0x00003800 +#define AM_REG_GPIO_PADREGH_PAD29FNCSEL(n) (((uint32_t)(n) << 11) & 0x00003800) +#define AM_REG_GPIO_PADREGH_PAD29FNCSEL_ADCSE1 0x00000000 +#define AM_REG_GPIO_PADREGH_PAD29FNCSEL_M1nCE6 0x00000800 +#define AM_REG_GPIO_PADREGH_PAD29FNCSEL_TCTA2 0x00001000 +#define AM_REG_GPIO_PADREGH_PAD29FNCSEL_GPIO29 0x00001800 +#define AM_REG_GPIO_PADREGH_PAD29FNCSEL_UA0CTS 0x00002000 +#define AM_REG_GPIO_PADREGH_PAD29FNCSEL_UA1CTS 0x00002800 +#define AM_REG_GPIO_PADREGH_PAD29FNCSEL_M4nCE0 0x00003000 +#define AM_REG_GPIO_PADREGH_PAD29FNCSEL_PDM_DATA 0x00003800 + +// Pad 29 drive strength +#define AM_REG_GPIO_PADREGH_PAD29STRNG_S 10 +#define AM_REG_GPIO_PADREGH_PAD29STRNG_M 0x00000400 +#define AM_REG_GPIO_PADREGH_PAD29STRNG(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_GPIO_PADREGH_PAD29STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGH_PAD29STRNG_HIGH 0x00000400 + +// Pad 29 input enable +#define AM_REG_GPIO_PADREGH_PAD29INPEN_S 9 +#define AM_REG_GPIO_PADREGH_PAD29INPEN_M 0x00000200 +#define AM_REG_GPIO_PADREGH_PAD29INPEN(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_GPIO_PADREGH_PAD29INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGH_PAD29INPEN_EN 0x00000200 + +// Pad 29 pullup enable +#define AM_REG_GPIO_PADREGH_PAD29PULL_S 8 +#define AM_REG_GPIO_PADREGH_PAD29PULL_M 0x00000100 +#define AM_REG_GPIO_PADREGH_PAD29PULL(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_PADREGH_PAD29PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGH_PAD29PULL_EN 0x00000100 + +// Pad 28 function select +#define AM_REG_GPIO_PADREGH_PAD28FNCSEL_S 3 +#define AM_REG_GPIO_PADREGH_PAD28FNCSEL_M 0x00000038 +#define AM_REG_GPIO_PADREGH_PAD28FNCSEL(n) (((uint32_t)(n) << 3) & 0x00000038) +#define AM_REG_GPIO_PADREGH_PAD28FNCSEL_I2S_WCLK 0x00000000 +#define AM_REG_GPIO_PADREGH_PAD28FNCSEL_M1nCE5 0x00000008 +#define AM_REG_GPIO_PADREGH_PAD28FNCSEL_TCTB1 0x00000010 +#define AM_REG_GPIO_PADREGH_PAD28FNCSEL_GPIO28 0x00000018 +#define AM_REG_GPIO_PADREGH_PAD28FNCSEL_M2WIR3 0x00000020 +#define AM_REG_GPIO_PADREGH_PAD28FNCSEL_M2MOSI 0x00000028 +#define AM_REG_GPIO_PADREGH_PAD28FNCSEL_M5nCE3 0x00000030 +#define AM_REG_GPIO_PADREGH_PAD28FNCSEL_SLWIR3LB 0x00000038 + +// Pad 28 drive strength +#define AM_REG_GPIO_PADREGH_PAD28STRNG_S 2 +#define AM_REG_GPIO_PADREGH_PAD28STRNG_M 0x00000004 +#define AM_REG_GPIO_PADREGH_PAD28STRNG(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_GPIO_PADREGH_PAD28STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGH_PAD28STRNG_HIGH 0x00000004 + +// Pad 28 input enable +#define AM_REG_GPIO_PADREGH_PAD28INPEN_S 1 +#define AM_REG_GPIO_PADREGH_PAD28INPEN_M 0x00000002 +#define AM_REG_GPIO_PADREGH_PAD28INPEN(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_GPIO_PADREGH_PAD28INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGH_PAD28INPEN_EN 0x00000002 + +// Pad 28 pullup enable +#define AM_REG_GPIO_PADREGH_PAD28PULL_S 0 +#define AM_REG_GPIO_PADREGH_PAD28PULL_M 0x00000001 +#define AM_REG_GPIO_PADREGH_PAD28PULL(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_PADREGH_PAD28PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGH_PAD28PULL_EN 0x00000001 + +//***************************************************************************** +// +// GPIO_PADREGI - Pad Configuration Register I +// +//***************************************************************************** +// Pad 35 function select +#define AM_REG_GPIO_PADREGI_PAD35FNCSEL_S 27 +#define AM_REG_GPIO_PADREGI_PAD35FNCSEL_M 0x38000000 +#define AM_REG_GPIO_PADREGI_PAD35FNCSEL(n) (((uint32_t)(n) << 27) & 0x38000000) +#define AM_REG_GPIO_PADREGI_PAD35FNCSEL_ADCSE7 0x00000000 +#define AM_REG_GPIO_PADREGI_PAD35FNCSEL_M1nCE0 0x08000000 +#define AM_REG_GPIO_PADREGI_PAD35FNCSEL_UART1TX 0x10000000 +#define AM_REG_GPIO_PADREGI_PAD35FNCSEL_GPIO35 0x18000000 +#define AM_REG_GPIO_PADREGI_PAD35FNCSEL_M4nCE6 0x20000000 +#define AM_REG_GPIO_PADREGI_PAD35FNCSEL_TCTA1 0x28000000 +#define AM_REG_GPIO_PADREGI_PAD35FNCSEL_UA0RTS 0x30000000 +#define AM_REG_GPIO_PADREGI_PAD35FNCSEL_M3nCE2 0x38000000 + +// Pad 35 drive strentgh +#define AM_REG_GPIO_PADREGI_PAD35STRNG_S 26 +#define AM_REG_GPIO_PADREGI_PAD35STRNG_M 0x04000000 +#define AM_REG_GPIO_PADREGI_PAD35STRNG(n) (((uint32_t)(n) << 26) & 0x04000000) +#define AM_REG_GPIO_PADREGI_PAD35STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGI_PAD35STRNG_HIGH 0x04000000 + +// Pad 35 input enable +#define AM_REG_GPIO_PADREGI_PAD35INPEN_S 25 +#define AM_REG_GPIO_PADREGI_PAD35INPEN_M 0x02000000 +#define AM_REG_GPIO_PADREGI_PAD35INPEN(n) (((uint32_t)(n) << 25) & 0x02000000) +#define AM_REG_GPIO_PADREGI_PAD35INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGI_PAD35INPEN_EN 0x02000000 + +// Pad 35 pullup enable +#define AM_REG_GPIO_PADREGI_PAD35PULL_S 24 +#define AM_REG_GPIO_PADREGI_PAD35PULL_M 0x01000000 +#define AM_REG_GPIO_PADREGI_PAD35PULL(n) (((uint32_t)(n) << 24) & 0x01000000) +#define AM_REG_GPIO_PADREGI_PAD35PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGI_PAD35PULL_EN 0x01000000 + +// Pad 34 function select +#define AM_REG_GPIO_PADREGI_PAD34FNCSEL_S 19 +#define AM_REG_GPIO_PADREGI_PAD34FNCSEL_M 0x00380000 +#define AM_REG_GPIO_PADREGI_PAD34FNCSEL(n) (((uint32_t)(n) << 19) & 0x00380000) +#define AM_REG_GPIO_PADREGI_PAD34FNCSEL_ADCSE6 0x00000000 +#define AM_REG_GPIO_PADREGI_PAD34FNCSEL_M0nCE7 0x00080000 +#define AM_REG_GPIO_PADREGI_PAD34FNCSEL_M2nCE3 0x00100000 +#define AM_REG_GPIO_PADREGI_PAD34FNCSEL_GPIO34 0x00180000 +#define AM_REG_GPIO_PADREGI_PAD34FNCSEL_CMPRF2 0x00200000 +#define AM_REG_GPIO_PADREGI_PAD34FNCSEL_M3nCE1 0x00280000 +#define AM_REG_GPIO_PADREGI_PAD34FNCSEL_M4nCE0 0x00300000 +#define AM_REG_GPIO_PADREGI_PAD34FNCSEL_M5nCE2 0x00380000 + +// Pad 34 drive strength +#define AM_REG_GPIO_PADREGI_PAD34STRNG_S 18 +#define AM_REG_GPIO_PADREGI_PAD34STRNG_M 0x00040000 +#define AM_REG_GPIO_PADREGI_PAD34STRNG(n) (((uint32_t)(n) << 18) & 0x00040000) +#define AM_REG_GPIO_PADREGI_PAD34STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGI_PAD34STRNG_HIGH 0x00040000 + +// Pad 34 input enable +#define AM_REG_GPIO_PADREGI_PAD34INPEN_S 17 +#define AM_REG_GPIO_PADREGI_PAD34INPEN_M 0x00020000 +#define AM_REG_GPIO_PADREGI_PAD34INPEN(n) (((uint32_t)(n) << 17) & 0x00020000) +#define AM_REG_GPIO_PADREGI_PAD34INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGI_PAD34INPEN_EN 0x00020000 + +// Pad 34 pullup enable +#define AM_REG_GPIO_PADREGI_PAD34PULL_S 16 +#define AM_REG_GPIO_PADREGI_PAD34PULL_M 0x00010000 +#define AM_REG_GPIO_PADREGI_PAD34PULL(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_GPIO_PADREGI_PAD34PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGI_PAD34PULL_EN 0x00010000 + +// Pad 33 function select +#define AM_REG_GPIO_PADREGI_PAD33FNCSEL_S 11 +#define AM_REG_GPIO_PADREGI_PAD33FNCSEL_M 0x00003800 +#define AM_REG_GPIO_PADREGI_PAD33FNCSEL(n) (((uint32_t)(n) << 11) & 0x00003800) +#define AM_REG_GPIO_PADREGI_PAD33FNCSEL_ADCSE5 0x00000000 +#define AM_REG_GPIO_PADREGI_PAD33FNCSEL_M0nCE6 0x00000800 +#define AM_REG_GPIO_PADREGI_PAD33FNCSEL_32khz_XT 0x00001000 +#define AM_REG_GPIO_PADREGI_PAD33FNCSEL_GPIO33 0x00001800 +#define AM_REG_GPIO_PADREGI_PAD33FNCSEL_UNDEF4 0x00002000 +#define AM_REG_GPIO_PADREGI_PAD33FNCSEL_M3nCE7 0x00002800 +#define AM_REG_GPIO_PADREGI_PAD33FNCSEL_TCTB1 0x00003000 +#define AM_REG_GPIO_PADREGI_PAD33FNCSEL_SWO 0x00003800 + +// Pad 33 drive strength +#define AM_REG_GPIO_PADREGI_PAD33STRNG_S 10 +#define AM_REG_GPIO_PADREGI_PAD33STRNG_M 0x00000400 +#define AM_REG_GPIO_PADREGI_PAD33STRNG(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_GPIO_PADREGI_PAD33STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGI_PAD33STRNG_HIGH 0x00000400 + +// Pad 33 input enable +#define AM_REG_GPIO_PADREGI_PAD33INPEN_S 9 +#define AM_REG_GPIO_PADREGI_PAD33INPEN_M 0x00000200 +#define AM_REG_GPIO_PADREGI_PAD33INPEN(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_GPIO_PADREGI_PAD33INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGI_PAD33INPEN_EN 0x00000200 + +// Pad 33 pullup enable +#define AM_REG_GPIO_PADREGI_PAD33PULL_S 8 +#define AM_REG_GPIO_PADREGI_PAD33PULL_M 0x00000100 +#define AM_REG_GPIO_PADREGI_PAD33PULL(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_PADREGI_PAD33PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGI_PAD33PULL_EN 0x00000100 + +// Pad 32 function select +#define AM_REG_GPIO_PADREGI_PAD32FNCSEL_S 3 +#define AM_REG_GPIO_PADREGI_PAD32FNCSEL_M 0x00000038 +#define AM_REG_GPIO_PADREGI_PAD32FNCSEL(n) (((uint32_t)(n) << 3) & 0x00000038) +#define AM_REG_GPIO_PADREGI_PAD32FNCSEL_ADCSE4 0x00000000 +#define AM_REG_GPIO_PADREGI_PAD32FNCSEL_M0nCE5 0x00000008 +#define AM_REG_GPIO_PADREGI_PAD32FNCSEL_TCTB3 0x00000010 +#define AM_REG_GPIO_PADREGI_PAD32FNCSEL_GPIO32 0x00000018 +#define AM_REG_GPIO_PADREGI_PAD32FNCSEL_UNDEF4 0x00000020 +#define AM_REG_GPIO_PADREGI_PAD32FNCSEL_TCTB1 0x00000028 +#define AM_REG_GPIO_PADREGI_PAD32FNCSEL_UNDEF6 0x00000030 +#define AM_REG_GPIO_PADREGI_PAD32FNCSEL_UNDEF7 0x00000038 + +// Pad 32 drive strength +#define AM_REG_GPIO_PADREGI_PAD32STRNG_S 2 +#define AM_REG_GPIO_PADREGI_PAD32STRNG_M 0x00000004 +#define AM_REG_GPIO_PADREGI_PAD32STRNG(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_GPIO_PADREGI_PAD32STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGI_PAD32STRNG_HIGH 0x00000004 + +// Pad 32 input enable +#define AM_REG_GPIO_PADREGI_PAD32INPEN_S 1 +#define AM_REG_GPIO_PADREGI_PAD32INPEN_M 0x00000002 +#define AM_REG_GPIO_PADREGI_PAD32INPEN(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_GPIO_PADREGI_PAD32INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGI_PAD32INPEN_EN 0x00000002 + +// Pad 32 pullup enable +#define AM_REG_GPIO_PADREGI_PAD32PULL_S 0 +#define AM_REG_GPIO_PADREGI_PAD32PULL_M 0x00000001 +#define AM_REG_GPIO_PADREGI_PAD32PULL(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_PADREGI_PAD32PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGI_PAD32PULL_EN 0x00000001 + +//***************************************************************************** +// +// GPIO_PADREGJ - Pad Configuration Register J +// +//***************************************************************************** +// Pad 39 pullup resistor selection. +#define AM_REG_GPIO_PADREGJ_PAD39RSEL_S 30 +#define AM_REG_GPIO_PADREGJ_PAD39RSEL_M 0xC0000000 +#define AM_REG_GPIO_PADREGJ_PAD39RSEL(n) (((uint32_t)(n) << 30) & 0xC0000000) +#define AM_REG_GPIO_PADREGJ_PAD39RSEL_PULL1_5K 0x00000000 +#define AM_REG_GPIO_PADREGJ_PAD39RSEL_PULL6K 0x40000000 +#define AM_REG_GPIO_PADREGJ_PAD39RSEL_PULL12K 0x80000000 +#define AM_REG_GPIO_PADREGJ_PAD39RSEL_PULL24K 0xC0000000 + +// Pad 39 function select +#define AM_REG_GPIO_PADREGJ_PAD39FNCSEL_S 27 +#define AM_REG_GPIO_PADREGJ_PAD39FNCSEL_M 0x38000000 +#define AM_REG_GPIO_PADREGJ_PAD39FNCSEL(n) (((uint32_t)(n) << 27) & 0x38000000) +#define AM_REG_GPIO_PADREGJ_PAD39FNCSEL_UART0TX 0x00000000 +#define AM_REG_GPIO_PADREGJ_PAD39FNCSEL_UART1TX 0x08000000 +#define AM_REG_GPIO_PADREGJ_PAD39FNCSEL_CLKOUT 0x10000000 +#define AM_REG_GPIO_PADREGJ_PAD39FNCSEL_GPIO39 0x18000000 +#define AM_REG_GPIO_PADREGJ_PAD39FNCSEL_M4SCL 0x20000000 +#define AM_REG_GPIO_PADREGJ_PAD39FNCSEL_M4SCK 0x28000000 +#define AM_REG_GPIO_PADREGJ_PAD39FNCSEL_M4SCKLB 0x30000000 +#define AM_REG_GPIO_PADREGJ_PAD39FNCSEL_M4SCLLB 0x38000000 + +// Pad 39 drive strentgh +#define AM_REG_GPIO_PADREGJ_PAD39STRNG_S 26 +#define AM_REG_GPIO_PADREGJ_PAD39STRNG_M 0x04000000 +#define AM_REG_GPIO_PADREGJ_PAD39STRNG(n) (((uint32_t)(n) << 26) & 0x04000000) +#define AM_REG_GPIO_PADREGJ_PAD39STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGJ_PAD39STRNG_HIGH 0x04000000 + +// Pad 39 input enable +#define AM_REG_GPIO_PADREGJ_PAD39INPEN_S 25 +#define AM_REG_GPIO_PADREGJ_PAD39INPEN_M 0x02000000 +#define AM_REG_GPIO_PADREGJ_PAD39INPEN(n) (((uint32_t)(n) << 25) & 0x02000000) +#define AM_REG_GPIO_PADREGJ_PAD39INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGJ_PAD39INPEN_EN 0x02000000 + +// Pad 39 pullup enable +#define AM_REG_GPIO_PADREGJ_PAD39PULL_S 24 +#define AM_REG_GPIO_PADREGJ_PAD39PULL_M 0x01000000 +#define AM_REG_GPIO_PADREGJ_PAD39PULL(n) (((uint32_t)(n) << 24) & 0x01000000) +#define AM_REG_GPIO_PADREGJ_PAD39PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGJ_PAD39PULL_EN 0x01000000 + +// Pad 38 function select +#define AM_REG_GPIO_PADREGJ_PAD38FNCSEL_S 19 +#define AM_REG_GPIO_PADREGJ_PAD38FNCSEL_M 0x00380000 +#define AM_REG_GPIO_PADREGJ_PAD38FNCSEL(n) (((uint32_t)(n) << 19) & 0x00380000) +#define AM_REG_GPIO_PADREGJ_PAD38FNCSEL_TRIG3 0x00000000 +#define AM_REG_GPIO_PADREGJ_PAD38FNCSEL_M1nCE3 0x00080000 +#define AM_REG_GPIO_PADREGJ_PAD38FNCSEL_UA0CTS 0x00100000 +#define AM_REG_GPIO_PADREGJ_PAD38FNCSEL_GPIO38 0x00180000 +#define AM_REG_GPIO_PADREGJ_PAD38FNCSEL_M3WIR3 0x00200000 +#define AM_REG_GPIO_PADREGJ_PAD38FNCSEL_M3MOSI 0x00280000 +#define AM_REG_GPIO_PADREGJ_PAD38FNCSEL_M4nCE7 0x00300000 +#define AM_REG_GPIO_PADREGJ_PAD38FNCSEL_SLWIR3LB 0x00380000 + +// Pad 38 drive strength +#define AM_REG_GPIO_PADREGJ_PAD38STRNG_S 18 +#define AM_REG_GPIO_PADREGJ_PAD38STRNG_M 0x00040000 +#define AM_REG_GPIO_PADREGJ_PAD38STRNG(n) (((uint32_t)(n) << 18) & 0x00040000) +#define AM_REG_GPIO_PADREGJ_PAD38STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGJ_PAD38STRNG_HIGH 0x00040000 + +// Pad 38 input enable +#define AM_REG_GPIO_PADREGJ_PAD38INPEN_S 17 +#define AM_REG_GPIO_PADREGJ_PAD38INPEN_M 0x00020000 +#define AM_REG_GPIO_PADREGJ_PAD38INPEN(n) (((uint32_t)(n) << 17) & 0x00020000) +#define AM_REG_GPIO_PADREGJ_PAD38INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGJ_PAD38INPEN_EN 0x00020000 + +// Pad 38 pullup enable +#define AM_REG_GPIO_PADREGJ_PAD38PULL_S 16 +#define AM_REG_GPIO_PADREGJ_PAD38PULL_M 0x00010000 +#define AM_REG_GPIO_PADREGJ_PAD38PULL(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_GPIO_PADREGJ_PAD38PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGJ_PAD38PULL_EN 0x00010000 + +// Pad 37 function select +#define AM_REG_GPIO_PADREGJ_PAD37FNCSEL_S 11 +#define AM_REG_GPIO_PADREGJ_PAD37FNCSEL_M 0x00003800 +#define AM_REG_GPIO_PADREGJ_PAD37FNCSEL(n) (((uint32_t)(n) << 11) & 0x00003800) +#define AM_REG_GPIO_PADREGJ_PAD37FNCSEL_TRIG2 0x00000000 +#define AM_REG_GPIO_PADREGJ_PAD37FNCSEL_M1nCE2 0x00000800 +#define AM_REG_GPIO_PADREGJ_PAD37FNCSEL_UA0RTS 0x00001000 +#define AM_REG_GPIO_PADREGJ_PAD37FNCSEL_GPIO37 0x00001800 +#define AM_REG_GPIO_PADREGJ_PAD37FNCSEL_M3nCE4 0x00002000 +#define AM_REG_GPIO_PADREGJ_PAD37FNCSEL_M4nCE1 0x00002800 +#define AM_REG_GPIO_PADREGJ_PAD37FNCSEL_PDM_CLK 0x00003000 +#define AM_REG_GPIO_PADREGJ_PAD37FNCSEL_TCTA1 0x00003800 + +// Pad 37 drive strength +#define AM_REG_GPIO_PADREGJ_PAD37STRNG_S 10 +#define AM_REG_GPIO_PADREGJ_PAD37STRNG_M 0x00000400 +#define AM_REG_GPIO_PADREGJ_PAD37STRNG(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_GPIO_PADREGJ_PAD37STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGJ_PAD37STRNG_HIGH 0x00000400 + +// Pad 37 input enable +#define AM_REG_GPIO_PADREGJ_PAD37INPEN_S 9 +#define AM_REG_GPIO_PADREGJ_PAD37INPEN_M 0x00000200 +#define AM_REG_GPIO_PADREGJ_PAD37INPEN(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_GPIO_PADREGJ_PAD37INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGJ_PAD37INPEN_EN 0x00000200 + +// Pad 37 pullup enable +#define AM_REG_GPIO_PADREGJ_PAD37PULL_S 8 +#define AM_REG_GPIO_PADREGJ_PAD37PULL_M 0x00000100 +#define AM_REG_GPIO_PADREGJ_PAD37PULL(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_PADREGJ_PAD37PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGJ_PAD37PULL_EN 0x00000100 + +// Pad 36 function select +#define AM_REG_GPIO_PADREGJ_PAD36FNCSEL_S 3 +#define AM_REG_GPIO_PADREGJ_PAD36FNCSEL_M 0x00000038 +#define AM_REG_GPIO_PADREGJ_PAD36FNCSEL(n) (((uint32_t)(n) << 3) & 0x00000038) +#define AM_REG_GPIO_PADREGJ_PAD36FNCSEL_TRIG1 0x00000000 +#define AM_REG_GPIO_PADREGJ_PAD36FNCSEL_M1nCE1 0x00000008 +#define AM_REG_GPIO_PADREGJ_PAD36FNCSEL_UART1RX 0x00000010 +#define AM_REG_GPIO_PADREGJ_PAD36FNCSEL_GPIO36 0x00000018 +#define AM_REG_GPIO_PADREGJ_PAD36FNCSEL_32khz_XT 0x00000020 +#define AM_REG_GPIO_PADREGJ_PAD36FNCSEL_M2nCE0 0x00000028 +#define AM_REG_GPIO_PADREGJ_PAD36FNCSEL_UA0CTS 0x00000030 +#define AM_REG_GPIO_PADREGJ_PAD36FNCSEL_M3nCE3 0x00000038 + +// Pad 36 drive strength +#define AM_REG_GPIO_PADREGJ_PAD36STRNG_S 2 +#define AM_REG_GPIO_PADREGJ_PAD36STRNG_M 0x00000004 +#define AM_REG_GPIO_PADREGJ_PAD36STRNG(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_GPIO_PADREGJ_PAD36STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGJ_PAD36STRNG_HIGH 0x00000004 + +// Pad 36 input enable +#define AM_REG_GPIO_PADREGJ_PAD36INPEN_S 1 +#define AM_REG_GPIO_PADREGJ_PAD36INPEN_M 0x00000002 +#define AM_REG_GPIO_PADREGJ_PAD36INPEN(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_GPIO_PADREGJ_PAD36INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGJ_PAD36INPEN_EN 0x00000002 + +// Pad 36 pullup enable +#define AM_REG_GPIO_PADREGJ_PAD36PULL_S 0 +#define AM_REG_GPIO_PADREGJ_PAD36PULL_M 0x00000001 +#define AM_REG_GPIO_PADREGJ_PAD36PULL(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_PADREGJ_PAD36PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGJ_PAD36PULL_EN 0x00000001 + +//***************************************************************************** +// +// GPIO_PADREGK - Pad Configuration Register K +// +//***************************************************************************** +// Pad 43 pullup resistor selection. +#define AM_REG_GPIO_PADREGK_PAD43RSEL_S 30 +#define AM_REG_GPIO_PADREGK_PAD43RSEL_M 0xC0000000 +#define AM_REG_GPIO_PADREGK_PAD43RSEL(n) (((uint32_t)(n) << 30) & 0xC0000000) +#define AM_REG_GPIO_PADREGK_PAD43RSEL_PULL1_5K 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD43RSEL_PULL6K 0x40000000 +#define AM_REG_GPIO_PADREGK_PAD43RSEL_PULL12K 0x80000000 +#define AM_REG_GPIO_PADREGK_PAD43RSEL_PULL24K 0xC0000000 + +// Pad 43 function select +#define AM_REG_GPIO_PADREGK_PAD43FNCSEL_S 27 +#define AM_REG_GPIO_PADREGK_PAD43FNCSEL_M 0x38000000 +#define AM_REG_GPIO_PADREGK_PAD43FNCSEL(n) (((uint32_t)(n) << 27) & 0x38000000) +#define AM_REG_GPIO_PADREGK_PAD43FNCSEL_M2nCE4 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD43FNCSEL_M0nCE1 0x08000000 +#define AM_REG_GPIO_PADREGK_PAD43FNCSEL_TCTB0 0x10000000 +#define AM_REG_GPIO_PADREGK_PAD43FNCSEL_GPIO43 0x18000000 +#define AM_REG_GPIO_PADREGK_PAD43FNCSEL_M3SDA 0x20000000 +#define AM_REG_GPIO_PADREGK_PAD43FNCSEL_M3MISO 0x28000000 +#define AM_REG_GPIO_PADREGK_PAD43FNCSEL_SLMISOLB 0x30000000 +#define AM_REG_GPIO_PADREGK_PAD43FNCSEL_SLSDALB 0x38000000 + +// Pad 43 drive strentgh +#define AM_REG_GPIO_PADREGK_PAD43STRNG_S 26 +#define AM_REG_GPIO_PADREGK_PAD43STRNG_M 0x04000000 +#define AM_REG_GPIO_PADREGK_PAD43STRNG(n) (((uint32_t)(n) << 26) & 0x04000000) +#define AM_REG_GPIO_PADREGK_PAD43STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD43STRNG_HIGH 0x04000000 + +// Pad 43 input enable +#define AM_REG_GPIO_PADREGK_PAD43INPEN_S 25 +#define AM_REG_GPIO_PADREGK_PAD43INPEN_M 0x02000000 +#define AM_REG_GPIO_PADREGK_PAD43INPEN(n) (((uint32_t)(n) << 25) & 0x02000000) +#define AM_REG_GPIO_PADREGK_PAD43INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD43INPEN_EN 0x02000000 + +// Pad 43 pullup enable +#define AM_REG_GPIO_PADREGK_PAD43PULL_S 24 +#define AM_REG_GPIO_PADREGK_PAD43PULL_M 0x01000000 +#define AM_REG_GPIO_PADREGK_PAD43PULL(n) (((uint32_t)(n) << 24) & 0x01000000) +#define AM_REG_GPIO_PADREGK_PAD43PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD43PULL_EN 0x01000000 + +// Pad 42 pullup resistor selection. +#define AM_REG_GPIO_PADREGK_PAD42RSEL_S 22 +#define AM_REG_GPIO_PADREGK_PAD42RSEL_M 0x00C00000 +#define AM_REG_GPIO_PADREGK_PAD42RSEL(n) (((uint32_t)(n) << 22) & 0x00C00000) +#define AM_REG_GPIO_PADREGK_PAD42RSEL_PULL1_5K 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD42RSEL_PULL6K 0x00400000 +#define AM_REG_GPIO_PADREGK_PAD42RSEL_PULL12K 0x00800000 +#define AM_REG_GPIO_PADREGK_PAD42RSEL_PULL24K 0x00C00000 + +// Pad 42 function select +#define AM_REG_GPIO_PADREGK_PAD42FNCSEL_S 19 +#define AM_REG_GPIO_PADREGK_PAD42FNCSEL_M 0x00380000 +#define AM_REG_GPIO_PADREGK_PAD42FNCSEL(n) (((uint32_t)(n) << 19) & 0x00380000) +#define AM_REG_GPIO_PADREGK_PAD42FNCSEL_M2nCE2 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD42FNCSEL_M0nCE0 0x00080000 +#define AM_REG_GPIO_PADREGK_PAD42FNCSEL_TCTA0 0x00100000 +#define AM_REG_GPIO_PADREGK_PAD42FNCSEL_GPIO42 0x00180000 +#define AM_REG_GPIO_PADREGK_PAD42FNCSEL_M3SCL 0x00200000 +#define AM_REG_GPIO_PADREGK_PAD42FNCSEL_M3SCK 0x00280000 +#define AM_REG_GPIO_PADREGK_PAD42FNCSEL_M3SCKLB 0x00300000 +#define AM_REG_GPIO_PADREGK_PAD42FNCSEL_M3SCLLB 0x00380000 + +// Pad 42 drive strength +#define AM_REG_GPIO_PADREGK_PAD42STRNG_S 18 +#define AM_REG_GPIO_PADREGK_PAD42STRNG_M 0x00040000 +#define AM_REG_GPIO_PADREGK_PAD42STRNG(n) (((uint32_t)(n) << 18) & 0x00040000) +#define AM_REG_GPIO_PADREGK_PAD42STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD42STRNG_HIGH 0x00040000 + +// Pad 42 input enable +#define AM_REG_GPIO_PADREGK_PAD42INPEN_S 17 +#define AM_REG_GPIO_PADREGK_PAD42INPEN_M 0x00020000 +#define AM_REG_GPIO_PADREGK_PAD42INPEN(n) (((uint32_t)(n) << 17) & 0x00020000) +#define AM_REG_GPIO_PADREGK_PAD42INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD42INPEN_EN 0x00020000 + +// Pad 42 pullup enable +#define AM_REG_GPIO_PADREGK_PAD42PULL_S 16 +#define AM_REG_GPIO_PADREGK_PAD42PULL_M 0x00010000 +#define AM_REG_GPIO_PADREGK_PAD42PULL(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_GPIO_PADREGK_PAD42PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD42PULL_EN 0x00010000 + +// Pad 41 upper power switch enable +#define AM_REG_GPIO_PADREGK_PAD41PWRUP_S 15 +#define AM_REG_GPIO_PADREGK_PAD41PWRUP_M 0x00008000 +#define AM_REG_GPIO_PADREGK_PAD41PWRUP(n) (((uint32_t)(n) << 15) & 0x00008000) +#define AM_REG_GPIO_PADREGK_PAD41PWRUP_DIS 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD41PWRUP_EN 0x00008000 + +// Pad 41 function select +#define AM_REG_GPIO_PADREGK_PAD41FNCSEL_S 11 +#define AM_REG_GPIO_PADREGK_PAD41FNCSEL_M 0x00003800 +#define AM_REG_GPIO_PADREGK_PAD41FNCSEL(n) (((uint32_t)(n) << 11) & 0x00003800) +#define AM_REG_GPIO_PADREGK_PAD41FNCSEL_M2nCE1 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD41FNCSEL_CLKOUT 0x00000800 +#define AM_REG_GPIO_PADREGK_PAD41FNCSEL_SWO 0x00001000 +#define AM_REG_GPIO_PADREGK_PAD41FNCSEL_GPIO41 0x00001800 +#define AM_REG_GPIO_PADREGK_PAD41FNCSEL_M3nCE5 0x00002000 +#define AM_REG_GPIO_PADREGK_PAD41FNCSEL_M5nCE7 0x00002800 +#define AM_REG_GPIO_PADREGK_PAD41FNCSEL_M4nCE2 0x00003000 +#define AM_REG_GPIO_PADREGK_PAD41FNCSEL_UA0RTS 0x00003800 + +// Pad 41 drive strength +#define AM_REG_GPIO_PADREGK_PAD41STRNG_S 10 +#define AM_REG_GPIO_PADREGK_PAD41STRNG_M 0x00000400 +#define AM_REG_GPIO_PADREGK_PAD41STRNG(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_GPIO_PADREGK_PAD41STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD41STRNG_HIGH 0x00000400 + +// Pad 41 input enable +#define AM_REG_GPIO_PADREGK_PAD41INPEN_S 9 +#define AM_REG_GPIO_PADREGK_PAD41INPEN_M 0x00000200 +#define AM_REG_GPIO_PADREGK_PAD41INPEN(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_GPIO_PADREGK_PAD41INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD41INPEN_EN 0x00000200 + +// Pad 41 pullup enable +#define AM_REG_GPIO_PADREGK_PAD41PULL_S 8 +#define AM_REG_GPIO_PADREGK_PAD41PULL_M 0x00000100 +#define AM_REG_GPIO_PADREGK_PAD41PULL(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_PADREGK_PAD41PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD41PULL_EN 0x00000100 + +// Pad 40 pullup resistor selection. +#define AM_REG_GPIO_PADREGK_PAD40RSEL_S 6 +#define AM_REG_GPIO_PADREGK_PAD40RSEL_M 0x000000C0 +#define AM_REG_GPIO_PADREGK_PAD40RSEL(n) (((uint32_t)(n) << 6) & 0x000000C0) +#define AM_REG_GPIO_PADREGK_PAD40RSEL_PULL1_5K 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD40RSEL_PULL6K 0x00000040 +#define AM_REG_GPIO_PADREGK_PAD40RSEL_PULL12K 0x00000080 +#define AM_REG_GPIO_PADREGK_PAD40RSEL_PULL24K 0x000000C0 + +// Pad 40 function select +#define AM_REG_GPIO_PADREGK_PAD40FNCSEL_S 3 +#define AM_REG_GPIO_PADREGK_PAD40FNCSEL_M 0x00000038 +#define AM_REG_GPIO_PADREGK_PAD40FNCSEL(n) (((uint32_t)(n) << 3) & 0x00000038) +#define AM_REG_GPIO_PADREGK_PAD40FNCSEL_UART0RX 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD40FNCSEL_UART1RX 0x00000008 +#define AM_REG_GPIO_PADREGK_PAD40FNCSEL_TRIG0 0x00000010 +#define AM_REG_GPIO_PADREGK_PAD40FNCSEL_GPIO40 0x00000018 +#define AM_REG_GPIO_PADREGK_PAD40FNCSEL_M4SDA 0x00000020 +#define AM_REG_GPIO_PADREGK_PAD40FNCSEL_M4MISO 0x00000028 +#define AM_REG_GPIO_PADREGK_PAD40FNCSEL_SLMISOLB 0x00000030 +#define AM_REG_GPIO_PADREGK_PAD40FNCSEL_SLSDALB 0x00000038 + +// Pad 40 drive strength +#define AM_REG_GPIO_PADREGK_PAD40STRNG_S 2 +#define AM_REG_GPIO_PADREGK_PAD40STRNG_M 0x00000004 +#define AM_REG_GPIO_PADREGK_PAD40STRNG(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_GPIO_PADREGK_PAD40STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD40STRNG_HIGH 0x00000004 + +// Pad 40 input enable +#define AM_REG_GPIO_PADREGK_PAD40INPEN_S 1 +#define AM_REG_GPIO_PADREGK_PAD40INPEN_M 0x00000002 +#define AM_REG_GPIO_PADREGK_PAD40INPEN(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_GPIO_PADREGK_PAD40INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD40INPEN_EN 0x00000002 + +// Pad 40 pullup enable +#define AM_REG_GPIO_PADREGK_PAD40PULL_S 0 +#define AM_REG_GPIO_PADREGK_PAD40PULL_M 0x00000001 +#define AM_REG_GPIO_PADREGK_PAD40PULL(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_PADREGK_PAD40PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGK_PAD40PULL_EN 0x00000001 + +//***************************************************************************** +// +// GPIO_PADREGL - Pad Configuration Register L +// +//***************************************************************************** +// Pad 47 function select +#define AM_REG_GPIO_PADREGL_PAD47FNCSEL_S 27 +#define AM_REG_GPIO_PADREGL_PAD47FNCSEL_M 0x38000000 +#define AM_REG_GPIO_PADREGL_PAD47FNCSEL(n) (((uint32_t)(n) << 27) & 0x38000000) +#define AM_REG_GPIO_PADREGL_PAD47FNCSEL_M2nCE5 0x00000000 +#define AM_REG_GPIO_PADREGL_PAD47FNCSEL_M0nCE5 0x08000000 +#define AM_REG_GPIO_PADREGL_PAD47FNCSEL_TCTB2 0x10000000 +#define AM_REG_GPIO_PADREGL_PAD47FNCSEL_GPIO47 0x18000000 +#define AM_REG_GPIO_PADREGL_PAD47FNCSEL_M5WIR3 0x20000000 +#define AM_REG_GPIO_PADREGL_PAD47FNCSEL_M5MOSI 0x28000000 +#define AM_REG_GPIO_PADREGL_PAD47FNCSEL_M4nCE5 0x30000000 +#define AM_REG_GPIO_PADREGL_PAD47FNCSEL_SLWIR3LB 0x38000000 + +// Pad 47 drive strentgh +#define AM_REG_GPIO_PADREGL_PAD47STRNG_S 26 +#define AM_REG_GPIO_PADREGL_PAD47STRNG_M 0x04000000 +#define AM_REG_GPIO_PADREGL_PAD47STRNG(n) (((uint32_t)(n) << 26) & 0x04000000) +#define AM_REG_GPIO_PADREGL_PAD47STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGL_PAD47STRNG_HIGH 0x04000000 + +// Pad 47 input enable +#define AM_REG_GPIO_PADREGL_PAD47INPEN_S 25 +#define AM_REG_GPIO_PADREGL_PAD47INPEN_M 0x02000000 +#define AM_REG_GPIO_PADREGL_PAD47INPEN(n) (((uint32_t)(n) << 25) & 0x02000000) +#define AM_REG_GPIO_PADREGL_PAD47INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGL_PAD47INPEN_EN 0x02000000 + +// Pad 47 pullup enable +#define AM_REG_GPIO_PADREGL_PAD47PULL_S 24 +#define AM_REG_GPIO_PADREGL_PAD47PULL_M 0x01000000 +#define AM_REG_GPIO_PADREGL_PAD47PULL(n) (((uint32_t)(n) << 24) & 0x01000000) +#define AM_REG_GPIO_PADREGL_PAD47PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGL_PAD47PULL_EN 0x01000000 + +// Pad 46 function select +#define AM_REG_GPIO_PADREGL_PAD46FNCSEL_S 19 +#define AM_REG_GPIO_PADREGL_PAD46FNCSEL_M 0x00380000 +#define AM_REG_GPIO_PADREGL_PAD46FNCSEL(n) (((uint32_t)(n) << 19) & 0x00380000) +#define AM_REG_GPIO_PADREGL_PAD46FNCSEL_32khz_XT 0x00000000 +#define AM_REG_GPIO_PADREGL_PAD46FNCSEL_M0nCE4 0x00080000 +#define AM_REG_GPIO_PADREGL_PAD46FNCSEL_TCTA2 0x00100000 +#define AM_REG_GPIO_PADREGL_PAD46FNCSEL_GPIO46 0x00180000 +#define AM_REG_GPIO_PADREGL_PAD46FNCSEL_TCTA1 0x00200000 +#define AM_REG_GPIO_PADREGL_PAD46FNCSEL_M5nCE4 0x00280000 +#define AM_REG_GPIO_PADREGL_PAD46FNCSEL_M4nCE4 0x00300000 +#define AM_REG_GPIO_PADREGL_PAD46FNCSEL_SWO 0x00380000 + +// Pad 46 drive strength +#define AM_REG_GPIO_PADREGL_PAD46STRNG_S 18 +#define AM_REG_GPIO_PADREGL_PAD46STRNG_M 0x00040000 +#define AM_REG_GPIO_PADREGL_PAD46STRNG(n) (((uint32_t)(n) << 18) & 0x00040000) +#define AM_REG_GPIO_PADREGL_PAD46STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGL_PAD46STRNG_HIGH 0x00040000 + +// Pad 46 input enable +#define AM_REG_GPIO_PADREGL_PAD46INPEN_S 17 +#define AM_REG_GPIO_PADREGL_PAD46INPEN_M 0x00020000 +#define AM_REG_GPIO_PADREGL_PAD46INPEN(n) (((uint32_t)(n) << 17) & 0x00020000) +#define AM_REG_GPIO_PADREGL_PAD46INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGL_PAD46INPEN_EN 0x00020000 + +// Pad 46 pullup enable +#define AM_REG_GPIO_PADREGL_PAD46PULL_S 16 +#define AM_REG_GPIO_PADREGL_PAD46PULL_M 0x00010000 +#define AM_REG_GPIO_PADREGL_PAD46PULL(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_GPIO_PADREGL_PAD46PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGL_PAD46PULL_EN 0x00010000 + +// Pad 45 function select +#define AM_REG_GPIO_PADREGL_PAD45FNCSEL_S 11 +#define AM_REG_GPIO_PADREGL_PAD45FNCSEL_M 0x00003800 +#define AM_REG_GPIO_PADREGL_PAD45FNCSEL(n) (((uint32_t)(n) << 11) & 0x00003800) +#define AM_REG_GPIO_PADREGL_PAD45FNCSEL_UA1CTS 0x00000000 +#define AM_REG_GPIO_PADREGL_PAD45FNCSEL_M0nCE3 0x00000800 +#define AM_REG_GPIO_PADREGL_PAD45FNCSEL_TCTB1 0x00001000 +#define AM_REG_GPIO_PADREGL_PAD45FNCSEL_GPIO45 0x00001800 +#define AM_REG_GPIO_PADREGL_PAD45FNCSEL_M4nCE3 0x00002000 +#define AM_REG_GPIO_PADREGL_PAD45FNCSEL_M3nCE6 0x00002800 +#define AM_REG_GPIO_PADREGL_PAD45FNCSEL_M5nCE5 0x00003000 +#define AM_REG_GPIO_PADREGL_PAD45FNCSEL_TCTA1 0x00003800 + +// Pad 45 drive strength +#define AM_REG_GPIO_PADREGL_PAD45STRNG_S 10 +#define AM_REG_GPIO_PADREGL_PAD45STRNG_M 0x00000400 +#define AM_REG_GPIO_PADREGL_PAD45STRNG(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_GPIO_PADREGL_PAD45STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGL_PAD45STRNG_HIGH 0x00000400 + +// Pad 45 input enable +#define AM_REG_GPIO_PADREGL_PAD45INPEN_S 9 +#define AM_REG_GPIO_PADREGL_PAD45INPEN_M 0x00000200 +#define AM_REG_GPIO_PADREGL_PAD45INPEN(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_GPIO_PADREGL_PAD45INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGL_PAD45INPEN_EN 0x00000200 + +// Pad 45 pullup enable +#define AM_REG_GPIO_PADREGL_PAD45PULL_S 8 +#define AM_REG_GPIO_PADREGL_PAD45PULL_M 0x00000100 +#define AM_REG_GPIO_PADREGL_PAD45PULL(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_PADREGL_PAD45PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGL_PAD45PULL_EN 0x00000100 + +// Pad 44 function select +#define AM_REG_GPIO_PADREGL_PAD44FNCSEL_S 3 +#define AM_REG_GPIO_PADREGL_PAD44FNCSEL_M 0x00000038 +#define AM_REG_GPIO_PADREGL_PAD44FNCSEL(n) (((uint32_t)(n) << 3) & 0x00000038) +#define AM_REG_GPIO_PADREGL_PAD44FNCSEL_UA1RTS 0x00000000 +#define AM_REG_GPIO_PADREGL_PAD44FNCSEL_M0nCE2 0x00000008 +#define AM_REG_GPIO_PADREGL_PAD44FNCSEL_TCTA1 0x00000010 +#define AM_REG_GPIO_PADREGL_PAD44FNCSEL_GPIO44 0x00000018 +#define AM_REG_GPIO_PADREGL_PAD44FNCSEL_M4WIR3 0x00000020 +#define AM_REG_GPIO_PADREGL_PAD44FNCSEL_M4MOSI 0x00000028 +#define AM_REG_GPIO_PADREGL_PAD44FNCSEL_M5nCE6 0x00000030 +#define AM_REG_GPIO_PADREGL_PAD44FNCSEL_SLWIR3LB 0x00000038 + +// Pad 44 drive strength +#define AM_REG_GPIO_PADREGL_PAD44STRNG_S 2 +#define AM_REG_GPIO_PADREGL_PAD44STRNG_M 0x00000004 +#define AM_REG_GPIO_PADREGL_PAD44STRNG(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_GPIO_PADREGL_PAD44STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGL_PAD44STRNG_HIGH 0x00000004 + +// Pad 44 input enable +#define AM_REG_GPIO_PADREGL_PAD44INPEN_S 1 +#define AM_REG_GPIO_PADREGL_PAD44INPEN_M 0x00000002 +#define AM_REG_GPIO_PADREGL_PAD44INPEN(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_GPIO_PADREGL_PAD44INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGL_PAD44INPEN_EN 0x00000002 + +// Pad 44 pullup enable +#define AM_REG_GPIO_PADREGL_PAD44PULL_S 0 +#define AM_REG_GPIO_PADREGL_PAD44PULL_M 0x00000001 +#define AM_REG_GPIO_PADREGL_PAD44PULL(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_PADREGL_PAD44PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGL_PAD44PULL_EN 0x00000001 + +//***************************************************************************** +// +// GPIO_PADREGM - Pad Configuration Register M +// +//***************************************************************************** +// Pad 49 pullup resistor selection. +#define AM_REG_GPIO_PADREGM_PAD49RSEL_S 14 +#define AM_REG_GPIO_PADREGM_PAD49RSEL_M 0x0000C000 +#define AM_REG_GPIO_PADREGM_PAD49RSEL(n) (((uint32_t)(n) << 14) & 0x0000C000) +#define AM_REG_GPIO_PADREGM_PAD49RSEL_PULL1_5K 0x00000000 +#define AM_REG_GPIO_PADREGM_PAD49RSEL_PULL6K 0x00004000 +#define AM_REG_GPIO_PADREGM_PAD49RSEL_PULL12K 0x00008000 +#define AM_REG_GPIO_PADREGM_PAD49RSEL_PULL24K 0x0000C000 + +// Pad 49 function select +#define AM_REG_GPIO_PADREGM_PAD49FNCSEL_S 11 +#define AM_REG_GPIO_PADREGM_PAD49FNCSEL_M 0x00003800 +#define AM_REG_GPIO_PADREGM_PAD49FNCSEL(n) (((uint32_t)(n) << 11) & 0x00003800) +#define AM_REG_GPIO_PADREGM_PAD49FNCSEL_M2nCE7 0x00000000 +#define AM_REG_GPIO_PADREGM_PAD49FNCSEL_M0nCE7 0x00000800 +#define AM_REG_GPIO_PADREGM_PAD49FNCSEL_TCTB3 0x00001000 +#define AM_REG_GPIO_PADREGM_PAD49FNCSEL_GPIO49 0x00001800 +#define AM_REG_GPIO_PADREGM_PAD49FNCSEL_M5SDA 0x00002000 +#define AM_REG_GPIO_PADREGM_PAD49FNCSEL_M5MISO 0x00002800 +#define AM_REG_GPIO_PADREGM_PAD49FNCSEL_SLMISOLB 0x00003000 +#define AM_REG_GPIO_PADREGM_PAD49FNCSEL_SLSDALB 0x00003800 + +// Pad 49 drive strength +#define AM_REG_GPIO_PADREGM_PAD49STRNG_S 10 +#define AM_REG_GPIO_PADREGM_PAD49STRNG_M 0x00000400 +#define AM_REG_GPIO_PADREGM_PAD49STRNG(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_GPIO_PADREGM_PAD49STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGM_PAD49STRNG_HIGH 0x00000400 + +// Pad 49 input enable +#define AM_REG_GPIO_PADREGM_PAD49INPEN_S 9 +#define AM_REG_GPIO_PADREGM_PAD49INPEN_M 0x00000200 +#define AM_REG_GPIO_PADREGM_PAD49INPEN(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_GPIO_PADREGM_PAD49INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGM_PAD49INPEN_EN 0x00000200 + +// Pad 49 pullup enable +#define AM_REG_GPIO_PADREGM_PAD49PULL_S 8 +#define AM_REG_GPIO_PADREGM_PAD49PULL_M 0x00000100 +#define AM_REG_GPIO_PADREGM_PAD49PULL(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_PADREGM_PAD49PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGM_PAD49PULL_EN 0x00000100 + +// Pad 48 pullup resistor selection. +#define AM_REG_GPIO_PADREGM_PAD48RSEL_S 6 +#define AM_REG_GPIO_PADREGM_PAD48RSEL_M 0x000000C0 +#define AM_REG_GPIO_PADREGM_PAD48RSEL(n) (((uint32_t)(n) << 6) & 0x000000C0) +#define AM_REG_GPIO_PADREGM_PAD48RSEL_PULL1_5K 0x00000000 +#define AM_REG_GPIO_PADREGM_PAD48RSEL_PULL6K 0x00000040 +#define AM_REG_GPIO_PADREGM_PAD48RSEL_PULL12K 0x00000080 +#define AM_REG_GPIO_PADREGM_PAD48RSEL_PULL24K 0x000000C0 + +// Pad 48 function select +#define AM_REG_GPIO_PADREGM_PAD48FNCSEL_S 3 +#define AM_REG_GPIO_PADREGM_PAD48FNCSEL_M 0x00000038 +#define AM_REG_GPIO_PADREGM_PAD48FNCSEL(n) (((uint32_t)(n) << 3) & 0x00000038) +#define AM_REG_GPIO_PADREGM_PAD48FNCSEL_M2nCE6 0x00000000 +#define AM_REG_GPIO_PADREGM_PAD48FNCSEL_M0nCE6 0x00000008 +#define AM_REG_GPIO_PADREGM_PAD48FNCSEL_TCTA3 0x00000010 +#define AM_REG_GPIO_PADREGM_PAD48FNCSEL_GPIO48 0x00000018 +#define AM_REG_GPIO_PADREGM_PAD48FNCSEL_M5SCL 0x00000020 +#define AM_REG_GPIO_PADREGM_PAD48FNCSEL_M5SCK 0x00000028 +#define AM_REG_GPIO_PADREGM_PAD48FNCSEL_M5SCKLB 0x00000030 +#define AM_REG_GPIO_PADREGM_PAD48FNCSEL_M5SCLLB 0x00000038 + +// Pad 48 drive strength +#define AM_REG_GPIO_PADREGM_PAD48STRNG_S 2 +#define AM_REG_GPIO_PADREGM_PAD48STRNG_M 0x00000004 +#define AM_REG_GPIO_PADREGM_PAD48STRNG(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_GPIO_PADREGM_PAD48STRNG_LOW 0x00000000 +#define AM_REG_GPIO_PADREGM_PAD48STRNG_HIGH 0x00000004 + +// Pad 48 input enable +#define AM_REG_GPIO_PADREGM_PAD48INPEN_S 1 +#define AM_REG_GPIO_PADREGM_PAD48INPEN_M 0x00000002 +#define AM_REG_GPIO_PADREGM_PAD48INPEN(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_GPIO_PADREGM_PAD48INPEN_DIS 0x00000000 +#define AM_REG_GPIO_PADREGM_PAD48INPEN_EN 0x00000002 + +// Pad 48 pullup enable +#define AM_REG_GPIO_PADREGM_PAD48PULL_S 0 +#define AM_REG_GPIO_PADREGM_PAD48PULL_M 0x00000001 +#define AM_REG_GPIO_PADREGM_PAD48PULL(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_PADREGM_PAD48PULL_DIS 0x00000000 +#define AM_REG_GPIO_PADREGM_PAD48PULL_EN 0x00000001 + +//***************************************************************************** +// +// GPIO_CFGA - GPIO Configuration Register A +// +//***************************************************************************** +// GPIO7 interrupt direction. +#define AM_REG_GPIO_CFGA_GPIO7INTD_S 31 +#define AM_REG_GPIO_CFGA_GPIO7INTD_M 0x80000000 +#define AM_REG_GPIO_CFGA_GPIO7INTD(n) (((uint32_t)(n) << 31) & 0x80000000) +#define AM_REG_GPIO_CFGA_GPIO7INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO7INTD_INTHL 0x80000000 + +// GPIO7 output configuration. +#define AM_REG_GPIO_CFGA_GPIO7OUTCFG_S 29 +#define AM_REG_GPIO_CFGA_GPIO7OUTCFG_M 0x60000000 +#define AM_REG_GPIO_CFGA_GPIO7OUTCFG(n) (((uint32_t)(n) << 29) & 0x60000000) +#define AM_REG_GPIO_CFGA_GPIO7OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO7OUTCFG_PUSHPULL 0x20000000 +#define AM_REG_GPIO_CFGA_GPIO7OUTCFG_OD 0x40000000 +#define AM_REG_GPIO_CFGA_GPIO7OUTCFG_TS 0x60000000 + +// GPIO7 input enable. +#define AM_REG_GPIO_CFGA_GPIO7INCFG_S 28 +#define AM_REG_GPIO_CFGA_GPIO7INCFG_M 0x10000000 +#define AM_REG_GPIO_CFGA_GPIO7INCFG(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_GPIO_CFGA_GPIO7INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO7INCFG_RDZERO 0x10000000 + +// GPIO6 interrupt direction. +#define AM_REG_GPIO_CFGA_GPIO6INTD_S 27 +#define AM_REG_GPIO_CFGA_GPIO6INTD_M 0x08000000 +#define AM_REG_GPIO_CFGA_GPIO6INTD(n) (((uint32_t)(n) << 27) & 0x08000000) +#define AM_REG_GPIO_CFGA_GPIO6INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO6INTD_INTHL 0x08000000 + +// GPIO6 output configuration. +#define AM_REG_GPIO_CFGA_GPIO6OUTCFG_S 25 +#define AM_REG_GPIO_CFGA_GPIO6OUTCFG_M 0x06000000 +#define AM_REG_GPIO_CFGA_GPIO6OUTCFG(n) (((uint32_t)(n) << 25) & 0x06000000) +#define AM_REG_GPIO_CFGA_GPIO6OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO6OUTCFG_PUSHPULL 0x02000000 +#define AM_REG_GPIO_CFGA_GPIO6OUTCFG_OD 0x04000000 +#define AM_REG_GPIO_CFGA_GPIO6OUTCFG_TS 0x06000000 + +// GPIO6 input enable. +#define AM_REG_GPIO_CFGA_GPIO6INCFG_S 24 +#define AM_REG_GPIO_CFGA_GPIO6INCFG_M 0x01000000 +#define AM_REG_GPIO_CFGA_GPIO6INCFG(n) (((uint32_t)(n) << 24) & 0x01000000) +#define AM_REG_GPIO_CFGA_GPIO6INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO6INCFG_RDZERO 0x01000000 + +// GPIO5 interrupt direction. +#define AM_REG_GPIO_CFGA_GPIO5INTD_S 23 +#define AM_REG_GPIO_CFGA_GPIO5INTD_M 0x00800000 +#define AM_REG_GPIO_CFGA_GPIO5INTD(n) (((uint32_t)(n) << 23) & 0x00800000) +#define AM_REG_GPIO_CFGA_GPIO5INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO5INTD_INTHL 0x00800000 + +// GPIO5 output configuration. +#define AM_REG_GPIO_CFGA_GPIO5OUTCFG_S 21 +#define AM_REG_GPIO_CFGA_GPIO5OUTCFG_M 0x00600000 +#define AM_REG_GPIO_CFGA_GPIO5OUTCFG(n) (((uint32_t)(n) << 21) & 0x00600000) +#define AM_REG_GPIO_CFGA_GPIO5OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO5OUTCFG_PUSHPULL 0x00200000 +#define AM_REG_GPIO_CFGA_GPIO5OUTCFG_OD 0x00400000 +#define AM_REG_GPIO_CFGA_GPIO5OUTCFG_TS 0x00600000 + +// GPIO5 input enable. +#define AM_REG_GPIO_CFGA_GPIO5INCFG_S 20 +#define AM_REG_GPIO_CFGA_GPIO5INCFG_M 0x00100000 +#define AM_REG_GPIO_CFGA_GPIO5INCFG(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_GPIO_CFGA_GPIO5INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO5INCFG_RDZERO 0x00100000 + +// GPIO4 interrupt direction. +#define AM_REG_GPIO_CFGA_GPIO4INTD_S 19 +#define AM_REG_GPIO_CFGA_GPIO4INTD_M 0x00080000 +#define AM_REG_GPIO_CFGA_GPIO4INTD(n) (((uint32_t)(n) << 19) & 0x00080000) +#define AM_REG_GPIO_CFGA_GPIO4INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO4INTD_INTHL 0x00080000 + +// GPIO4 output configuration. +#define AM_REG_GPIO_CFGA_GPIO4OUTCFG_S 17 +#define AM_REG_GPIO_CFGA_GPIO4OUTCFG_M 0x00060000 +#define AM_REG_GPIO_CFGA_GPIO4OUTCFG(n) (((uint32_t)(n) << 17) & 0x00060000) +#define AM_REG_GPIO_CFGA_GPIO4OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO4OUTCFG_PUSHPULL 0x00020000 +#define AM_REG_GPIO_CFGA_GPIO4OUTCFG_OD 0x00040000 +#define AM_REG_GPIO_CFGA_GPIO4OUTCFG_TS 0x00060000 + +// GPIO4 input enable. +#define AM_REG_GPIO_CFGA_GPIO4INCFG_S 16 +#define AM_REG_GPIO_CFGA_GPIO4INCFG_M 0x00010000 +#define AM_REG_GPIO_CFGA_GPIO4INCFG(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_GPIO_CFGA_GPIO4INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO4INCFG_RDZERO 0x00010000 + +// GPIO3 interrupt direction. +#define AM_REG_GPIO_CFGA_GPIO3INTD_S 15 +#define AM_REG_GPIO_CFGA_GPIO3INTD_M 0x00008000 +#define AM_REG_GPIO_CFGA_GPIO3INTD(n) (((uint32_t)(n) << 15) & 0x00008000) +#define AM_REG_GPIO_CFGA_GPIO3INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO3INTD_INTHL 0x00008000 + +// GPIO3 output configuration. +#define AM_REG_GPIO_CFGA_GPIO3OUTCFG_S 13 +#define AM_REG_GPIO_CFGA_GPIO3OUTCFG_M 0x00006000 +#define AM_REG_GPIO_CFGA_GPIO3OUTCFG(n) (((uint32_t)(n) << 13) & 0x00006000) +#define AM_REG_GPIO_CFGA_GPIO3OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO3OUTCFG_PUSHPULL 0x00002000 +#define AM_REG_GPIO_CFGA_GPIO3OUTCFG_OD 0x00004000 +#define AM_REG_GPIO_CFGA_GPIO3OUTCFG_TS 0x00006000 + +// GPIO3 input enable. +#define AM_REG_GPIO_CFGA_GPIO3INCFG_S 12 +#define AM_REG_GPIO_CFGA_GPIO3INCFG_M 0x00001000 +#define AM_REG_GPIO_CFGA_GPIO3INCFG(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_CFGA_GPIO3INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO3INCFG_RDZERO 0x00001000 + +// GPIO2 interrupt direction. +#define AM_REG_GPIO_CFGA_GPIO2INTD_S 11 +#define AM_REG_GPIO_CFGA_GPIO2INTD_M 0x00000800 +#define AM_REG_GPIO_CFGA_GPIO2INTD(n) (((uint32_t)(n) << 11) & 0x00000800) +#define AM_REG_GPIO_CFGA_GPIO2INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO2INTD_INTHL 0x00000800 + +// GPIO2 output configuration. +#define AM_REG_GPIO_CFGA_GPIO2OUTCFG_S 9 +#define AM_REG_GPIO_CFGA_GPIO2OUTCFG_M 0x00000600 +#define AM_REG_GPIO_CFGA_GPIO2OUTCFG(n) (((uint32_t)(n) << 9) & 0x00000600) +#define AM_REG_GPIO_CFGA_GPIO2OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO2OUTCFG_PUSHPULL 0x00000200 +#define AM_REG_GPIO_CFGA_GPIO2OUTCFG_OD 0x00000400 +#define AM_REG_GPIO_CFGA_GPIO2OUTCFG_TS 0x00000600 + +// GPIO2 input enable. +#define AM_REG_GPIO_CFGA_GPIO2INCFG_S 8 +#define AM_REG_GPIO_CFGA_GPIO2INCFG_M 0x00000100 +#define AM_REG_GPIO_CFGA_GPIO2INCFG(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_CFGA_GPIO2INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO2INCFG_RDZERO 0x00000100 + +// GPIO1 interrupt direction. +#define AM_REG_GPIO_CFGA_GPIO1INTD_S 7 +#define AM_REG_GPIO_CFGA_GPIO1INTD_M 0x00000080 +#define AM_REG_GPIO_CFGA_GPIO1INTD(n) (((uint32_t)(n) << 7) & 0x00000080) +#define AM_REG_GPIO_CFGA_GPIO1INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO1INTD_INTHL 0x00000080 + +// GPIO1 output configuration. +#define AM_REG_GPIO_CFGA_GPIO1OUTCFG_S 5 +#define AM_REG_GPIO_CFGA_GPIO1OUTCFG_M 0x00000060 +#define AM_REG_GPIO_CFGA_GPIO1OUTCFG(n) (((uint32_t)(n) << 5) & 0x00000060) +#define AM_REG_GPIO_CFGA_GPIO1OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO1OUTCFG_PUSHPULL 0x00000020 +#define AM_REG_GPIO_CFGA_GPIO1OUTCFG_OD 0x00000040 +#define AM_REG_GPIO_CFGA_GPIO1OUTCFG_TS 0x00000060 + +// GPIO1 input enable. +#define AM_REG_GPIO_CFGA_GPIO1INCFG_S 4 +#define AM_REG_GPIO_CFGA_GPIO1INCFG_M 0x00000010 +#define AM_REG_GPIO_CFGA_GPIO1INCFG(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_CFGA_GPIO1INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO1INCFG_RDZERO 0x00000010 + +// GPIO0 interrupt direction. +#define AM_REG_GPIO_CFGA_GPIO0INTD_S 3 +#define AM_REG_GPIO_CFGA_GPIO0INTD_M 0x00000008 +#define AM_REG_GPIO_CFGA_GPIO0INTD(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_GPIO_CFGA_GPIO0INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO0INTD_INTHL 0x00000008 + +// GPIO0 output configuration. +#define AM_REG_GPIO_CFGA_GPIO0OUTCFG_S 1 +#define AM_REG_GPIO_CFGA_GPIO0OUTCFG_M 0x00000006 +#define AM_REG_GPIO_CFGA_GPIO0OUTCFG(n) (((uint32_t)(n) << 1) & 0x00000006) +#define AM_REG_GPIO_CFGA_GPIO0OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO0OUTCFG_PUSHPULL 0x00000002 +#define AM_REG_GPIO_CFGA_GPIO0OUTCFG_OD 0x00000004 +#define AM_REG_GPIO_CFGA_GPIO0OUTCFG_TS 0x00000006 + +// GPIO0 input enable. +#define AM_REG_GPIO_CFGA_GPIO0INCFG_S 0 +#define AM_REG_GPIO_CFGA_GPIO0INCFG_M 0x00000001 +#define AM_REG_GPIO_CFGA_GPIO0INCFG(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_CFGA_GPIO0INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGA_GPIO0INCFG_RDZERO 0x00000001 + +//***************************************************************************** +// +// GPIO_CFGB - GPIO Configuration Register B +// +//***************************************************************************** +// GPIO15 interrupt direction. +#define AM_REG_GPIO_CFGB_GPIO15INTD_S 31 +#define AM_REG_GPIO_CFGB_GPIO15INTD_M 0x80000000 +#define AM_REG_GPIO_CFGB_GPIO15INTD(n) (((uint32_t)(n) << 31) & 0x80000000) +#define AM_REG_GPIO_CFGB_GPIO15INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO15INTD_INTHL 0x80000000 + +// GPIO15 output configuration. +#define AM_REG_GPIO_CFGB_GPIO15OUTCFG_S 29 +#define AM_REG_GPIO_CFGB_GPIO15OUTCFG_M 0x60000000 +#define AM_REG_GPIO_CFGB_GPIO15OUTCFG(n) (((uint32_t)(n) << 29) & 0x60000000) +#define AM_REG_GPIO_CFGB_GPIO15OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO15OUTCFG_PUSHPULL 0x20000000 +#define AM_REG_GPIO_CFGB_GPIO15OUTCFG_OD 0x40000000 +#define AM_REG_GPIO_CFGB_GPIO15OUTCFG_TS 0x60000000 + +// GPIO15 input enable. +#define AM_REG_GPIO_CFGB_GPIO15INCFG_S 28 +#define AM_REG_GPIO_CFGB_GPIO15INCFG_M 0x10000000 +#define AM_REG_GPIO_CFGB_GPIO15INCFG(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_GPIO_CFGB_GPIO15INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO15INCFG_RDZERO 0x10000000 + +// GPIO14 interrupt direction. +#define AM_REG_GPIO_CFGB_GPIO14INTD_S 27 +#define AM_REG_GPIO_CFGB_GPIO14INTD_M 0x08000000 +#define AM_REG_GPIO_CFGB_GPIO14INTD(n) (((uint32_t)(n) << 27) & 0x08000000) +#define AM_REG_GPIO_CFGB_GPIO14INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO14INTD_INTHL 0x08000000 + +// GPIO14 output configuration. +#define AM_REG_GPIO_CFGB_GPIO14OUTCFG_S 25 +#define AM_REG_GPIO_CFGB_GPIO14OUTCFG_M 0x06000000 +#define AM_REG_GPIO_CFGB_GPIO14OUTCFG(n) (((uint32_t)(n) << 25) & 0x06000000) +#define AM_REG_GPIO_CFGB_GPIO14OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO14OUTCFG_PUSHPULL 0x02000000 +#define AM_REG_GPIO_CFGB_GPIO14OUTCFG_OD 0x04000000 +#define AM_REG_GPIO_CFGB_GPIO14OUTCFG_TS 0x06000000 + +// GPIO14 input enable. +#define AM_REG_GPIO_CFGB_GPIO14INCFG_S 24 +#define AM_REG_GPIO_CFGB_GPIO14INCFG_M 0x01000000 +#define AM_REG_GPIO_CFGB_GPIO14INCFG(n) (((uint32_t)(n) << 24) & 0x01000000) +#define AM_REG_GPIO_CFGB_GPIO14INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO14INCFG_RDZERO 0x01000000 + +// GPIO13 interrupt direction. +#define AM_REG_GPIO_CFGB_GPIO13INTD_S 23 +#define AM_REG_GPIO_CFGB_GPIO13INTD_M 0x00800000 +#define AM_REG_GPIO_CFGB_GPIO13INTD(n) (((uint32_t)(n) << 23) & 0x00800000) +#define AM_REG_GPIO_CFGB_GPIO13INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO13INTD_INTHL 0x00800000 + +// GPIO13 output configuration. +#define AM_REG_GPIO_CFGB_GPIO13OUTCFG_S 21 +#define AM_REG_GPIO_CFGB_GPIO13OUTCFG_M 0x00600000 +#define AM_REG_GPIO_CFGB_GPIO13OUTCFG(n) (((uint32_t)(n) << 21) & 0x00600000) +#define AM_REG_GPIO_CFGB_GPIO13OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO13OUTCFG_PUSHPULL 0x00200000 +#define AM_REG_GPIO_CFGB_GPIO13OUTCFG_OD 0x00400000 +#define AM_REG_GPIO_CFGB_GPIO13OUTCFG_TS 0x00600000 + +// GPIO13 input enable. +#define AM_REG_GPIO_CFGB_GPIO13INCFG_S 20 +#define AM_REG_GPIO_CFGB_GPIO13INCFG_M 0x00100000 +#define AM_REG_GPIO_CFGB_GPIO13INCFG(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_GPIO_CFGB_GPIO13INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO13INCFG_RDZERO 0x00100000 + +// GPIO12 interrupt direction. +#define AM_REG_GPIO_CFGB_GPIO12INTD_S 19 +#define AM_REG_GPIO_CFGB_GPIO12INTD_M 0x00080000 +#define AM_REG_GPIO_CFGB_GPIO12INTD(n) (((uint32_t)(n) << 19) & 0x00080000) +#define AM_REG_GPIO_CFGB_GPIO12INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO12INTD_INTHL 0x00080000 + +// GPIO12 output configuration. +#define AM_REG_GPIO_CFGB_GPIO12OUTCFG_S 17 +#define AM_REG_GPIO_CFGB_GPIO12OUTCFG_M 0x00060000 +#define AM_REG_GPIO_CFGB_GPIO12OUTCFG(n) (((uint32_t)(n) << 17) & 0x00060000) +#define AM_REG_GPIO_CFGB_GPIO12OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO12OUTCFG_PUSHPULL 0x00020000 +#define AM_REG_GPIO_CFGB_GPIO12OUTCFG_OD 0x00040000 +#define AM_REG_GPIO_CFGB_GPIO12OUTCFG_TS 0x00060000 + +// GPIO12 input enable. +#define AM_REG_GPIO_CFGB_GPIO12INCFG_S 16 +#define AM_REG_GPIO_CFGB_GPIO12INCFG_M 0x00010000 +#define AM_REG_GPIO_CFGB_GPIO12INCFG(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_GPIO_CFGB_GPIO12INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO12INCFG_RDZERO 0x00010000 + +// GPIO11 interrupt direction. +#define AM_REG_GPIO_CFGB_GPIO11INTD_S 15 +#define AM_REG_GPIO_CFGB_GPIO11INTD_M 0x00008000 +#define AM_REG_GPIO_CFGB_GPIO11INTD(n) (((uint32_t)(n) << 15) & 0x00008000) +#define AM_REG_GPIO_CFGB_GPIO11INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO11INTD_INTHL 0x00008000 + +// GPIO11 output configuration. +#define AM_REG_GPIO_CFGB_GPIO11OUTCFG_S 13 +#define AM_REG_GPIO_CFGB_GPIO11OUTCFG_M 0x00006000 +#define AM_REG_GPIO_CFGB_GPIO11OUTCFG(n) (((uint32_t)(n) << 13) & 0x00006000) +#define AM_REG_GPIO_CFGB_GPIO11OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO11OUTCFG_PUSHPULL 0x00002000 +#define AM_REG_GPIO_CFGB_GPIO11OUTCFG_OD 0x00004000 +#define AM_REG_GPIO_CFGB_GPIO11OUTCFG_TS 0x00006000 + +// GPIO11 input enable. +#define AM_REG_GPIO_CFGB_GPIO11INCFG_S 12 +#define AM_REG_GPIO_CFGB_GPIO11INCFG_M 0x00001000 +#define AM_REG_GPIO_CFGB_GPIO11INCFG(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_CFGB_GPIO11INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO11INCFG_RDZERO 0x00001000 + +// GPIO10 interrupt direction. +#define AM_REG_GPIO_CFGB_GPIO10INTD_S 11 +#define AM_REG_GPIO_CFGB_GPIO10INTD_M 0x00000800 +#define AM_REG_GPIO_CFGB_GPIO10INTD(n) (((uint32_t)(n) << 11) & 0x00000800) +#define AM_REG_GPIO_CFGB_GPIO10INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO10INTD_INTHL 0x00000800 + +// GPIO10 output configuration. +#define AM_REG_GPIO_CFGB_GPIO10OUTCFG_S 9 +#define AM_REG_GPIO_CFGB_GPIO10OUTCFG_M 0x00000600 +#define AM_REG_GPIO_CFGB_GPIO10OUTCFG(n) (((uint32_t)(n) << 9) & 0x00000600) +#define AM_REG_GPIO_CFGB_GPIO10OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO10OUTCFG_PUSHPULL 0x00000200 +#define AM_REG_GPIO_CFGB_GPIO10OUTCFG_OD 0x00000400 +#define AM_REG_GPIO_CFGB_GPIO10OUTCFG_TS 0x00000600 + +// GPIO10 input enable. +#define AM_REG_GPIO_CFGB_GPIO10INCFG_S 8 +#define AM_REG_GPIO_CFGB_GPIO10INCFG_M 0x00000100 +#define AM_REG_GPIO_CFGB_GPIO10INCFG(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_CFGB_GPIO10INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO10INCFG_RDZERO 0x00000100 + +// GPIO9 interrupt direction. +#define AM_REG_GPIO_CFGB_GPIO9INTD_S 7 +#define AM_REG_GPIO_CFGB_GPIO9INTD_M 0x00000080 +#define AM_REG_GPIO_CFGB_GPIO9INTD(n) (((uint32_t)(n) << 7) & 0x00000080) +#define AM_REG_GPIO_CFGB_GPIO9INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO9INTD_INTHL 0x00000080 + +// GPIO9 output configuration. +#define AM_REG_GPIO_CFGB_GPIO9OUTCFG_S 5 +#define AM_REG_GPIO_CFGB_GPIO9OUTCFG_M 0x00000060 +#define AM_REG_GPIO_CFGB_GPIO9OUTCFG(n) (((uint32_t)(n) << 5) & 0x00000060) +#define AM_REG_GPIO_CFGB_GPIO9OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO9OUTCFG_PUSHPULL 0x00000020 +#define AM_REG_GPIO_CFGB_GPIO9OUTCFG_OD 0x00000040 +#define AM_REG_GPIO_CFGB_GPIO9OUTCFG_TS 0x00000060 + +// GPIO9 input enable. +#define AM_REG_GPIO_CFGB_GPIO9INCFG_S 4 +#define AM_REG_GPIO_CFGB_GPIO9INCFG_M 0x00000010 +#define AM_REG_GPIO_CFGB_GPIO9INCFG(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_CFGB_GPIO9INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO9INCFG_RDZERO 0x00000010 + +// GPIO8 interrupt direction. +#define AM_REG_GPIO_CFGB_GPIO8INTD_S 3 +#define AM_REG_GPIO_CFGB_GPIO8INTD_M 0x00000008 +#define AM_REG_GPIO_CFGB_GPIO8INTD(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_GPIO_CFGB_GPIO8INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO8INTD_INTHL 0x00000008 + +// GPIO8 output configuration. +#define AM_REG_GPIO_CFGB_GPIO8OUTCFG_S 1 +#define AM_REG_GPIO_CFGB_GPIO8OUTCFG_M 0x00000006 +#define AM_REG_GPIO_CFGB_GPIO8OUTCFG(n) (((uint32_t)(n) << 1) & 0x00000006) +#define AM_REG_GPIO_CFGB_GPIO8OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO8OUTCFG_PUSHPULL 0x00000002 +#define AM_REG_GPIO_CFGB_GPIO8OUTCFG_OD 0x00000004 +#define AM_REG_GPIO_CFGB_GPIO8OUTCFG_TS 0x00000006 + +// GPIO8 input enable. +#define AM_REG_GPIO_CFGB_GPIO8INCFG_S 0 +#define AM_REG_GPIO_CFGB_GPIO8INCFG_M 0x00000001 +#define AM_REG_GPIO_CFGB_GPIO8INCFG(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_CFGB_GPIO8INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGB_GPIO8INCFG_RDZERO 0x00000001 + +//***************************************************************************** +// +// GPIO_CFGC - GPIO Configuration Register C +// +//***************************************************************************** +// GPIO23 interrupt direction. +#define AM_REG_GPIO_CFGC_GPIO23INTD_S 31 +#define AM_REG_GPIO_CFGC_GPIO23INTD_M 0x80000000 +#define AM_REG_GPIO_CFGC_GPIO23INTD(n) (((uint32_t)(n) << 31) & 0x80000000) +#define AM_REG_GPIO_CFGC_GPIO23INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO23INTD_INTHL 0x80000000 + +// GPIO23 output configuration. +#define AM_REG_GPIO_CFGC_GPIO23OUTCFG_S 29 +#define AM_REG_GPIO_CFGC_GPIO23OUTCFG_M 0x60000000 +#define AM_REG_GPIO_CFGC_GPIO23OUTCFG(n) (((uint32_t)(n) << 29) & 0x60000000) +#define AM_REG_GPIO_CFGC_GPIO23OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO23OUTCFG_PUSHPULL 0x20000000 +#define AM_REG_GPIO_CFGC_GPIO23OUTCFG_OD 0x40000000 +#define AM_REG_GPIO_CFGC_GPIO23OUTCFG_TS 0x60000000 + +// GPIO23 input enable. +#define AM_REG_GPIO_CFGC_GPIO23INCFG_S 28 +#define AM_REG_GPIO_CFGC_GPIO23INCFG_M 0x10000000 +#define AM_REG_GPIO_CFGC_GPIO23INCFG(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_GPIO_CFGC_GPIO23INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO23INCFG_RDZERO 0x10000000 + +// GPIO22 interrupt direction. +#define AM_REG_GPIO_CFGC_GPIO22INTD_S 27 +#define AM_REG_GPIO_CFGC_GPIO22INTD_M 0x08000000 +#define AM_REG_GPIO_CFGC_GPIO22INTD(n) (((uint32_t)(n) << 27) & 0x08000000) +#define AM_REG_GPIO_CFGC_GPIO22INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO22INTD_INTHL 0x08000000 + +// GPIO22 output configuration. +#define AM_REG_GPIO_CFGC_GPIO22OUTCFG_S 25 +#define AM_REG_GPIO_CFGC_GPIO22OUTCFG_M 0x06000000 +#define AM_REG_GPIO_CFGC_GPIO22OUTCFG(n) (((uint32_t)(n) << 25) & 0x06000000) +#define AM_REG_GPIO_CFGC_GPIO22OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO22OUTCFG_PUSHPULL 0x02000000 +#define AM_REG_GPIO_CFGC_GPIO22OUTCFG_OD 0x04000000 +#define AM_REG_GPIO_CFGC_GPIO22OUTCFG_TS 0x06000000 + +// GPIO22 input enable. +#define AM_REG_GPIO_CFGC_GPIO22INCFG_S 24 +#define AM_REG_GPIO_CFGC_GPIO22INCFG_M 0x01000000 +#define AM_REG_GPIO_CFGC_GPIO22INCFG(n) (((uint32_t)(n) << 24) & 0x01000000) +#define AM_REG_GPIO_CFGC_GPIO22INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO22INCFG_RDZERO 0x01000000 + +// GPIO21 interrupt direction. +#define AM_REG_GPIO_CFGC_GPIO21INTD_S 23 +#define AM_REG_GPIO_CFGC_GPIO21INTD_M 0x00800000 +#define AM_REG_GPIO_CFGC_GPIO21INTD(n) (((uint32_t)(n) << 23) & 0x00800000) +#define AM_REG_GPIO_CFGC_GPIO21INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO21INTD_INTHL 0x00800000 + +// GPIO21 output configuration. +#define AM_REG_GPIO_CFGC_GPIO21OUTCFG_S 21 +#define AM_REG_GPIO_CFGC_GPIO21OUTCFG_M 0x00600000 +#define AM_REG_GPIO_CFGC_GPIO21OUTCFG(n) (((uint32_t)(n) << 21) & 0x00600000) +#define AM_REG_GPIO_CFGC_GPIO21OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO21OUTCFG_PUSHPULL 0x00200000 +#define AM_REG_GPIO_CFGC_GPIO21OUTCFG_OD 0x00400000 +#define AM_REG_GPIO_CFGC_GPIO21OUTCFG_TS 0x00600000 + +// GPIO21 input enable. +#define AM_REG_GPIO_CFGC_GPIO21INCFG_S 20 +#define AM_REG_GPIO_CFGC_GPIO21INCFG_M 0x00100000 +#define AM_REG_GPIO_CFGC_GPIO21INCFG(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_GPIO_CFGC_GPIO21INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO21INCFG_RDZERO 0x00100000 + +// GPIO20 interrupt direction. +#define AM_REG_GPIO_CFGC_GPIO20INTD_S 19 +#define AM_REG_GPIO_CFGC_GPIO20INTD_M 0x00080000 +#define AM_REG_GPIO_CFGC_GPIO20INTD(n) (((uint32_t)(n) << 19) & 0x00080000) +#define AM_REG_GPIO_CFGC_GPIO20INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO20INTD_INTHL 0x00080000 + +// GPIO20 output configuration. +#define AM_REG_GPIO_CFGC_GPIO20OUTCFG_S 17 +#define AM_REG_GPIO_CFGC_GPIO20OUTCFG_M 0x00060000 +#define AM_REG_GPIO_CFGC_GPIO20OUTCFG(n) (((uint32_t)(n) << 17) & 0x00060000) +#define AM_REG_GPIO_CFGC_GPIO20OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO20OUTCFG_PUSHPULL 0x00020000 +#define AM_REG_GPIO_CFGC_GPIO20OUTCFG_OD 0x00040000 +#define AM_REG_GPIO_CFGC_GPIO20OUTCFG_TS 0x00060000 + +// GPIO20 input enable. +#define AM_REG_GPIO_CFGC_GPIO20INCFG_S 16 +#define AM_REG_GPIO_CFGC_GPIO20INCFG_M 0x00010000 +#define AM_REG_GPIO_CFGC_GPIO20INCFG(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_GPIO_CFGC_GPIO20INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO20INCFG_RDZERO 0x00010000 + +// GPIO19 interrupt direction. +#define AM_REG_GPIO_CFGC_GPIO19INTD_S 15 +#define AM_REG_GPIO_CFGC_GPIO19INTD_M 0x00008000 +#define AM_REG_GPIO_CFGC_GPIO19INTD(n) (((uint32_t)(n) << 15) & 0x00008000) +#define AM_REG_GPIO_CFGC_GPIO19INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO19INTD_INTHL 0x00008000 + +// GPIO19 output configuration. +#define AM_REG_GPIO_CFGC_GPIO19OUTCFG_S 13 +#define AM_REG_GPIO_CFGC_GPIO19OUTCFG_M 0x00006000 +#define AM_REG_GPIO_CFGC_GPIO19OUTCFG(n) (((uint32_t)(n) << 13) & 0x00006000) +#define AM_REG_GPIO_CFGC_GPIO19OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO19OUTCFG_PUSHPULL 0x00002000 +#define AM_REG_GPIO_CFGC_GPIO19OUTCFG_OD 0x00004000 +#define AM_REG_GPIO_CFGC_GPIO19OUTCFG_TS 0x00006000 + +// GPIO19 input enable. +#define AM_REG_GPIO_CFGC_GPIO19INCFG_S 12 +#define AM_REG_GPIO_CFGC_GPIO19INCFG_M 0x00001000 +#define AM_REG_GPIO_CFGC_GPIO19INCFG(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_CFGC_GPIO19INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO19INCFG_RDZERO 0x00001000 + +// GPIO18 interrupt direction. +#define AM_REG_GPIO_CFGC_GPIO18INTD_S 11 +#define AM_REG_GPIO_CFGC_GPIO18INTD_M 0x00000800 +#define AM_REG_GPIO_CFGC_GPIO18INTD(n) (((uint32_t)(n) << 11) & 0x00000800) +#define AM_REG_GPIO_CFGC_GPIO18INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO18INTD_INTHL 0x00000800 + +// GPIO18 output configuration. +#define AM_REG_GPIO_CFGC_GPIO18OUTCFG_S 9 +#define AM_REG_GPIO_CFGC_GPIO18OUTCFG_M 0x00000600 +#define AM_REG_GPIO_CFGC_GPIO18OUTCFG(n) (((uint32_t)(n) << 9) & 0x00000600) +#define AM_REG_GPIO_CFGC_GPIO18OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO18OUTCFG_PUSHPULL 0x00000200 +#define AM_REG_GPIO_CFGC_GPIO18OUTCFG_OD 0x00000400 +#define AM_REG_GPIO_CFGC_GPIO18OUTCFG_TS 0x00000600 + +// GPIO18 input enable. +#define AM_REG_GPIO_CFGC_GPIO18INCFG_S 8 +#define AM_REG_GPIO_CFGC_GPIO18INCFG_M 0x00000100 +#define AM_REG_GPIO_CFGC_GPIO18INCFG(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_CFGC_GPIO18INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO18INCFG_RDZERO 0x00000100 + +// GPIO17 interrupt direction. +#define AM_REG_GPIO_CFGC_GPIO17INTD_S 7 +#define AM_REG_GPIO_CFGC_GPIO17INTD_M 0x00000080 +#define AM_REG_GPIO_CFGC_GPIO17INTD(n) (((uint32_t)(n) << 7) & 0x00000080) +#define AM_REG_GPIO_CFGC_GPIO17INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO17INTD_INTHL 0x00000080 + +// GPIO17 output configuration. +#define AM_REG_GPIO_CFGC_GPIO17OUTCFG_S 5 +#define AM_REG_GPIO_CFGC_GPIO17OUTCFG_M 0x00000060 +#define AM_REG_GPIO_CFGC_GPIO17OUTCFG(n) (((uint32_t)(n) << 5) & 0x00000060) +#define AM_REG_GPIO_CFGC_GPIO17OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO17OUTCFG_PUSHPULL 0x00000020 +#define AM_REG_GPIO_CFGC_GPIO17OUTCFG_OD 0x00000040 +#define AM_REG_GPIO_CFGC_GPIO17OUTCFG_TS 0x00000060 + +// GPIO17 input enable. +#define AM_REG_GPIO_CFGC_GPIO17INCFG_S 4 +#define AM_REG_GPIO_CFGC_GPIO17INCFG_M 0x00000010 +#define AM_REG_GPIO_CFGC_GPIO17INCFG(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_CFGC_GPIO17INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO17INCFG_RDZERO 0x00000010 + +// GPIO16 interrupt direction. +#define AM_REG_GPIO_CFGC_GPIO16INTD_S 3 +#define AM_REG_GPIO_CFGC_GPIO16INTD_M 0x00000008 +#define AM_REG_GPIO_CFGC_GPIO16INTD(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_GPIO_CFGC_GPIO16INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO16INTD_INTHL 0x00000008 + +// GPIO16 output configuration. +#define AM_REG_GPIO_CFGC_GPIO16OUTCFG_S 1 +#define AM_REG_GPIO_CFGC_GPIO16OUTCFG_M 0x00000006 +#define AM_REG_GPIO_CFGC_GPIO16OUTCFG(n) (((uint32_t)(n) << 1) & 0x00000006) +#define AM_REG_GPIO_CFGC_GPIO16OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO16OUTCFG_PUSHPULL 0x00000002 +#define AM_REG_GPIO_CFGC_GPIO16OUTCFG_OD 0x00000004 +#define AM_REG_GPIO_CFGC_GPIO16OUTCFG_TS 0x00000006 + +// GPIO16 input enable. +#define AM_REG_GPIO_CFGC_GPIO16INCFG_S 0 +#define AM_REG_GPIO_CFGC_GPIO16INCFG_M 0x00000001 +#define AM_REG_GPIO_CFGC_GPIO16INCFG(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_CFGC_GPIO16INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGC_GPIO16INCFG_RDZERO 0x00000001 + +//***************************************************************************** +// +// GPIO_CFGD - GPIO Configuration Register D +// +//***************************************************************************** +// GPIO31 interrupt direction. +#define AM_REG_GPIO_CFGD_GPIO31INTD_S 31 +#define AM_REG_GPIO_CFGD_GPIO31INTD_M 0x80000000 +#define AM_REG_GPIO_CFGD_GPIO31INTD(n) (((uint32_t)(n) << 31) & 0x80000000) +#define AM_REG_GPIO_CFGD_GPIO31INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO31INTD_INTHL 0x80000000 + +// GPIO31 output configuration. +#define AM_REG_GPIO_CFGD_GPIO31OUTCFG_S 29 +#define AM_REG_GPIO_CFGD_GPIO31OUTCFG_M 0x60000000 +#define AM_REG_GPIO_CFGD_GPIO31OUTCFG(n) (((uint32_t)(n) << 29) & 0x60000000) +#define AM_REG_GPIO_CFGD_GPIO31OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO31OUTCFG_PUSHPULL 0x20000000 +#define AM_REG_GPIO_CFGD_GPIO31OUTCFG_OD 0x40000000 +#define AM_REG_GPIO_CFGD_GPIO31OUTCFG_TS 0x60000000 + +// GPIO31 input enable. +#define AM_REG_GPIO_CFGD_GPIO31INCFG_S 28 +#define AM_REG_GPIO_CFGD_GPIO31INCFG_M 0x10000000 +#define AM_REG_GPIO_CFGD_GPIO31INCFG(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_GPIO_CFGD_GPIO31INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO31INCFG_RDZERO 0x10000000 + +// GPIO30 interrupt direction. +#define AM_REG_GPIO_CFGD_GPIO30INTD_S 27 +#define AM_REG_GPIO_CFGD_GPIO30INTD_M 0x08000000 +#define AM_REG_GPIO_CFGD_GPIO30INTD(n) (((uint32_t)(n) << 27) & 0x08000000) +#define AM_REG_GPIO_CFGD_GPIO30INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO30INTD_INTHL 0x08000000 + +// GPIO30 output configuration. +#define AM_REG_GPIO_CFGD_GPIO30OUTCFG_S 25 +#define AM_REG_GPIO_CFGD_GPIO30OUTCFG_M 0x06000000 +#define AM_REG_GPIO_CFGD_GPIO30OUTCFG(n) (((uint32_t)(n) << 25) & 0x06000000) +#define AM_REG_GPIO_CFGD_GPIO30OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO30OUTCFG_PUSHPULL 0x02000000 +#define AM_REG_GPIO_CFGD_GPIO30OUTCFG_OD 0x04000000 +#define AM_REG_GPIO_CFGD_GPIO30OUTCFG_TS 0x06000000 + +// GPIO30 input enable. +#define AM_REG_GPIO_CFGD_GPIO30INCFG_S 24 +#define AM_REG_GPIO_CFGD_GPIO30INCFG_M 0x01000000 +#define AM_REG_GPIO_CFGD_GPIO30INCFG(n) (((uint32_t)(n) << 24) & 0x01000000) +#define AM_REG_GPIO_CFGD_GPIO30INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO30INCFG_RDZERO 0x01000000 + +// GPIO29 interrupt direction. +#define AM_REG_GPIO_CFGD_GPIO29INTD_S 23 +#define AM_REG_GPIO_CFGD_GPIO29INTD_M 0x00800000 +#define AM_REG_GPIO_CFGD_GPIO29INTD(n) (((uint32_t)(n) << 23) & 0x00800000) +#define AM_REG_GPIO_CFGD_GPIO29INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO29INTD_INTHL 0x00800000 + +// GPIO29 output configuration. +#define AM_REG_GPIO_CFGD_GPIO29OUTCFG_S 21 +#define AM_REG_GPIO_CFGD_GPIO29OUTCFG_M 0x00600000 +#define AM_REG_GPIO_CFGD_GPIO29OUTCFG(n) (((uint32_t)(n) << 21) & 0x00600000) +#define AM_REG_GPIO_CFGD_GPIO29OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO29OUTCFG_PUSHPULL 0x00200000 +#define AM_REG_GPIO_CFGD_GPIO29OUTCFG_OD 0x00400000 +#define AM_REG_GPIO_CFGD_GPIO29OUTCFG_TS 0x00600000 + +// GPIO29 input enable. +#define AM_REG_GPIO_CFGD_GPIO29INCFG_S 20 +#define AM_REG_GPIO_CFGD_GPIO29INCFG_M 0x00100000 +#define AM_REG_GPIO_CFGD_GPIO29INCFG(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_GPIO_CFGD_GPIO29INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO29INCFG_RDZERO 0x00100000 + +// GPIO28 interrupt direction. +#define AM_REG_GPIO_CFGD_GPIO28INTD_S 19 +#define AM_REG_GPIO_CFGD_GPIO28INTD_M 0x00080000 +#define AM_REG_GPIO_CFGD_GPIO28INTD(n) (((uint32_t)(n) << 19) & 0x00080000) +#define AM_REG_GPIO_CFGD_GPIO28INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO28INTD_INTHL 0x00080000 + +// GPIO28 output configuration. +#define AM_REG_GPIO_CFGD_GPIO28OUTCFG_S 17 +#define AM_REG_GPIO_CFGD_GPIO28OUTCFG_M 0x00060000 +#define AM_REG_GPIO_CFGD_GPIO28OUTCFG(n) (((uint32_t)(n) << 17) & 0x00060000) +#define AM_REG_GPIO_CFGD_GPIO28OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO28OUTCFG_PUSHPULL 0x00020000 +#define AM_REG_GPIO_CFGD_GPIO28OUTCFG_OD 0x00040000 +#define AM_REG_GPIO_CFGD_GPIO28OUTCFG_TS 0x00060000 + +// GPIO28 input enable. +#define AM_REG_GPIO_CFGD_GPIO28INCFG_S 16 +#define AM_REG_GPIO_CFGD_GPIO28INCFG_M 0x00010000 +#define AM_REG_GPIO_CFGD_GPIO28INCFG(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_GPIO_CFGD_GPIO28INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO28INCFG_RDZERO 0x00010000 + +// GPIO27 interrupt direction. +#define AM_REG_GPIO_CFGD_GPIO27INTD_S 15 +#define AM_REG_GPIO_CFGD_GPIO27INTD_M 0x00008000 +#define AM_REG_GPIO_CFGD_GPIO27INTD(n) (((uint32_t)(n) << 15) & 0x00008000) +#define AM_REG_GPIO_CFGD_GPIO27INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO27INTD_INTHL 0x00008000 + +// GPIO27 output configuration. +#define AM_REG_GPIO_CFGD_GPIO27OUTCFG_S 13 +#define AM_REG_GPIO_CFGD_GPIO27OUTCFG_M 0x00006000 +#define AM_REG_GPIO_CFGD_GPIO27OUTCFG(n) (((uint32_t)(n) << 13) & 0x00006000) +#define AM_REG_GPIO_CFGD_GPIO27OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO27OUTCFG_PUSHPULL 0x00002000 +#define AM_REG_GPIO_CFGD_GPIO27OUTCFG_OD 0x00004000 +#define AM_REG_GPIO_CFGD_GPIO27OUTCFG_TS 0x00006000 + +// GPIO27 input enable. +#define AM_REG_GPIO_CFGD_GPIO27INCFG_S 12 +#define AM_REG_GPIO_CFGD_GPIO27INCFG_M 0x00001000 +#define AM_REG_GPIO_CFGD_GPIO27INCFG(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_CFGD_GPIO27INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO27INCFG_RDZERO 0x00001000 + +// GPIO26 interrupt direction. +#define AM_REG_GPIO_CFGD_GPIO26INTD_S 11 +#define AM_REG_GPIO_CFGD_GPIO26INTD_M 0x00000800 +#define AM_REG_GPIO_CFGD_GPIO26INTD(n) (((uint32_t)(n) << 11) & 0x00000800) +#define AM_REG_GPIO_CFGD_GPIO26INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO26INTD_INTHL 0x00000800 + +// GPIO26 output configuration. +#define AM_REG_GPIO_CFGD_GPIO26OUTCFG_S 9 +#define AM_REG_GPIO_CFGD_GPIO26OUTCFG_M 0x00000600 +#define AM_REG_GPIO_CFGD_GPIO26OUTCFG(n) (((uint32_t)(n) << 9) & 0x00000600) +#define AM_REG_GPIO_CFGD_GPIO26OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO26OUTCFG_PUSHPULL 0x00000200 +#define AM_REG_GPIO_CFGD_GPIO26OUTCFG_OD 0x00000400 +#define AM_REG_GPIO_CFGD_GPIO26OUTCFG_TS 0x00000600 + +// GPIO26 input enable. +#define AM_REG_GPIO_CFGD_GPIO26INCFG_S 8 +#define AM_REG_GPIO_CFGD_GPIO26INCFG_M 0x00000100 +#define AM_REG_GPIO_CFGD_GPIO26INCFG(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_CFGD_GPIO26INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO26INCFG_RDZERO 0x00000100 + +// GPIO25 interrupt direction. +#define AM_REG_GPIO_CFGD_GPIO25INTD_S 7 +#define AM_REG_GPIO_CFGD_GPIO25INTD_M 0x00000080 +#define AM_REG_GPIO_CFGD_GPIO25INTD(n) (((uint32_t)(n) << 7) & 0x00000080) +#define AM_REG_GPIO_CFGD_GPIO25INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO25INTD_INTHL 0x00000080 + +// GPIO25 output configuration. +#define AM_REG_GPIO_CFGD_GPIO25OUTCFG_S 5 +#define AM_REG_GPIO_CFGD_GPIO25OUTCFG_M 0x00000060 +#define AM_REG_GPIO_CFGD_GPIO25OUTCFG(n) (((uint32_t)(n) << 5) & 0x00000060) +#define AM_REG_GPIO_CFGD_GPIO25OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO25OUTCFG_PUSHPULL 0x00000020 +#define AM_REG_GPIO_CFGD_GPIO25OUTCFG_OD 0x00000040 +#define AM_REG_GPIO_CFGD_GPIO25OUTCFG_TS 0x00000060 + +// GPIO25 input enable. +#define AM_REG_GPIO_CFGD_GPIO25INCFG_S 4 +#define AM_REG_GPIO_CFGD_GPIO25INCFG_M 0x00000010 +#define AM_REG_GPIO_CFGD_GPIO25INCFG(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_CFGD_GPIO25INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO25INCFG_RDZERO 0x00000010 + +// GPIO24 interrupt direction. +#define AM_REG_GPIO_CFGD_GPIO24INTD_S 3 +#define AM_REG_GPIO_CFGD_GPIO24INTD_M 0x00000008 +#define AM_REG_GPIO_CFGD_GPIO24INTD(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_GPIO_CFGD_GPIO24INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO24INTD_INTHL 0x00000008 + +// GPIO24 output configuration. +#define AM_REG_GPIO_CFGD_GPIO24OUTCFG_S 1 +#define AM_REG_GPIO_CFGD_GPIO24OUTCFG_M 0x00000006 +#define AM_REG_GPIO_CFGD_GPIO24OUTCFG(n) (((uint32_t)(n) << 1) & 0x00000006) +#define AM_REG_GPIO_CFGD_GPIO24OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO24OUTCFG_PUSHPULL 0x00000002 +#define AM_REG_GPIO_CFGD_GPIO24OUTCFG_OD 0x00000004 +#define AM_REG_GPIO_CFGD_GPIO24OUTCFG_TS 0x00000006 + +// GPIO24 input enable. +#define AM_REG_GPIO_CFGD_GPIO24INCFG_S 0 +#define AM_REG_GPIO_CFGD_GPIO24INCFG_M 0x00000001 +#define AM_REG_GPIO_CFGD_GPIO24INCFG(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_CFGD_GPIO24INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGD_GPIO24INCFG_RDZERO 0x00000001 + +//***************************************************************************** +// +// GPIO_CFGE - GPIO Configuration Register E +// +//***************************************************************************** +// GPIO39 interrupt direction. +#define AM_REG_GPIO_CFGE_GPIO39INTD_S 31 +#define AM_REG_GPIO_CFGE_GPIO39INTD_M 0x80000000 +#define AM_REG_GPIO_CFGE_GPIO39INTD(n) (((uint32_t)(n) << 31) & 0x80000000) +#define AM_REG_GPIO_CFGE_GPIO39INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO39INTD_INTHL 0x80000000 + +// GPIO39 output configuration. +#define AM_REG_GPIO_CFGE_GPIO39OUTCFG_S 29 +#define AM_REG_GPIO_CFGE_GPIO39OUTCFG_M 0x60000000 +#define AM_REG_GPIO_CFGE_GPIO39OUTCFG(n) (((uint32_t)(n) << 29) & 0x60000000) +#define AM_REG_GPIO_CFGE_GPIO39OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO39OUTCFG_PUSHPULL 0x20000000 +#define AM_REG_GPIO_CFGE_GPIO39OUTCFG_OD 0x40000000 +#define AM_REG_GPIO_CFGE_GPIO39OUTCFG_TS 0x60000000 + +// GPIO39 input enable. +#define AM_REG_GPIO_CFGE_GPIO39INCFG_S 28 +#define AM_REG_GPIO_CFGE_GPIO39INCFG_M 0x10000000 +#define AM_REG_GPIO_CFGE_GPIO39INCFG(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_GPIO_CFGE_GPIO39INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO39INCFG_RDZERO 0x10000000 + +// GPIO38 interrupt direction. +#define AM_REG_GPIO_CFGE_GPIO38INTD_S 27 +#define AM_REG_GPIO_CFGE_GPIO38INTD_M 0x08000000 +#define AM_REG_GPIO_CFGE_GPIO38INTD(n) (((uint32_t)(n) << 27) & 0x08000000) +#define AM_REG_GPIO_CFGE_GPIO38INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO38INTD_INTHL 0x08000000 + +// GPIO38 output configuration. +#define AM_REG_GPIO_CFGE_GPIO38OUTCFG_S 25 +#define AM_REG_GPIO_CFGE_GPIO38OUTCFG_M 0x06000000 +#define AM_REG_GPIO_CFGE_GPIO38OUTCFG(n) (((uint32_t)(n) << 25) & 0x06000000) +#define AM_REG_GPIO_CFGE_GPIO38OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO38OUTCFG_PUSHPULL 0x02000000 +#define AM_REG_GPIO_CFGE_GPIO38OUTCFG_OD 0x04000000 +#define AM_REG_GPIO_CFGE_GPIO38OUTCFG_TS 0x06000000 + +// GPIO38 input enable. +#define AM_REG_GPIO_CFGE_GPIO38INCFG_S 24 +#define AM_REG_GPIO_CFGE_GPIO38INCFG_M 0x01000000 +#define AM_REG_GPIO_CFGE_GPIO38INCFG(n) (((uint32_t)(n) << 24) & 0x01000000) +#define AM_REG_GPIO_CFGE_GPIO38INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO38INCFG_RDZERO 0x01000000 + +// GPIO37 interrupt direction. +#define AM_REG_GPIO_CFGE_GPIO37INTD_S 23 +#define AM_REG_GPIO_CFGE_GPIO37INTD_M 0x00800000 +#define AM_REG_GPIO_CFGE_GPIO37INTD(n) (((uint32_t)(n) << 23) & 0x00800000) +#define AM_REG_GPIO_CFGE_GPIO37INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO37INTD_INTHL 0x00800000 + +// GPIO37 output configuration. +#define AM_REG_GPIO_CFGE_GPIO37OUTCFG_S 21 +#define AM_REG_GPIO_CFGE_GPIO37OUTCFG_M 0x00600000 +#define AM_REG_GPIO_CFGE_GPIO37OUTCFG(n) (((uint32_t)(n) << 21) & 0x00600000) +#define AM_REG_GPIO_CFGE_GPIO37OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO37OUTCFG_PUSHPULL 0x00200000 +#define AM_REG_GPIO_CFGE_GPIO37OUTCFG_OD 0x00400000 +#define AM_REG_GPIO_CFGE_GPIO37OUTCFG_TS 0x00600000 + +// GPIO37 input enable. +#define AM_REG_GPIO_CFGE_GPIO37INCFG_S 20 +#define AM_REG_GPIO_CFGE_GPIO37INCFG_M 0x00100000 +#define AM_REG_GPIO_CFGE_GPIO37INCFG(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_GPIO_CFGE_GPIO37INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO37INCFG_RDZERO 0x00100000 + +// GPIO36 interrupt direction. +#define AM_REG_GPIO_CFGE_GPIO36INTD_S 19 +#define AM_REG_GPIO_CFGE_GPIO36INTD_M 0x00080000 +#define AM_REG_GPIO_CFGE_GPIO36INTD(n) (((uint32_t)(n) << 19) & 0x00080000) +#define AM_REG_GPIO_CFGE_GPIO36INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO36INTD_INTHL 0x00080000 + +// GPIO36 output configuration. +#define AM_REG_GPIO_CFGE_GPIO36OUTCFG_S 17 +#define AM_REG_GPIO_CFGE_GPIO36OUTCFG_M 0x00060000 +#define AM_REG_GPIO_CFGE_GPIO36OUTCFG(n) (((uint32_t)(n) << 17) & 0x00060000) +#define AM_REG_GPIO_CFGE_GPIO36OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO36OUTCFG_PUSHPULL 0x00020000 +#define AM_REG_GPIO_CFGE_GPIO36OUTCFG_OD 0x00040000 +#define AM_REG_GPIO_CFGE_GPIO36OUTCFG_TS 0x00060000 + +// GPIO36 input enable. +#define AM_REG_GPIO_CFGE_GPIO36INCFG_S 16 +#define AM_REG_GPIO_CFGE_GPIO36INCFG_M 0x00010000 +#define AM_REG_GPIO_CFGE_GPIO36INCFG(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_GPIO_CFGE_GPIO36INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO36INCFG_RDZERO 0x00010000 + +// GPIO35 interrupt direction. +#define AM_REG_GPIO_CFGE_GPIO35INTD_S 15 +#define AM_REG_GPIO_CFGE_GPIO35INTD_M 0x00008000 +#define AM_REG_GPIO_CFGE_GPIO35INTD(n) (((uint32_t)(n) << 15) & 0x00008000) +#define AM_REG_GPIO_CFGE_GPIO35INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO35INTD_INTHL 0x00008000 + +// GPIO35 output configuration. +#define AM_REG_GPIO_CFGE_GPIO35OUTCFG_S 13 +#define AM_REG_GPIO_CFGE_GPIO35OUTCFG_M 0x00006000 +#define AM_REG_GPIO_CFGE_GPIO35OUTCFG(n) (((uint32_t)(n) << 13) & 0x00006000) +#define AM_REG_GPIO_CFGE_GPIO35OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO35OUTCFG_PUSHPULL 0x00002000 +#define AM_REG_GPIO_CFGE_GPIO35OUTCFG_OD 0x00004000 +#define AM_REG_GPIO_CFGE_GPIO35OUTCFG_TS 0x00006000 + +// GPIO35 input enable. +#define AM_REG_GPIO_CFGE_GPIO35INCFG_S 12 +#define AM_REG_GPIO_CFGE_GPIO35INCFG_M 0x00001000 +#define AM_REG_GPIO_CFGE_GPIO35INCFG(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_CFGE_GPIO35INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO35INCFG_RDZERO 0x00001000 + +// GPIO34 interrupt direction. +#define AM_REG_GPIO_CFGE_GPIO34INTD_S 11 +#define AM_REG_GPIO_CFGE_GPIO34INTD_M 0x00000800 +#define AM_REG_GPIO_CFGE_GPIO34INTD(n) (((uint32_t)(n) << 11) & 0x00000800) +#define AM_REG_GPIO_CFGE_GPIO34INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO34INTD_INTHL 0x00000800 + +// GPIO34 output configuration. +#define AM_REG_GPIO_CFGE_GPIO34OUTCFG_S 9 +#define AM_REG_GPIO_CFGE_GPIO34OUTCFG_M 0x00000600 +#define AM_REG_GPIO_CFGE_GPIO34OUTCFG(n) (((uint32_t)(n) << 9) & 0x00000600) +#define AM_REG_GPIO_CFGE_GPIO34OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO34OUTCFG_PUSHPULL 0x00000200 +#define AM_REG_GPIO_CFGE_GPIO34OUTCFG_OD 0x00000400 +#define AM_REG_GPIO_CFGE_GPIO34OUTCFG_TS 0x00000600 + +// GPIO34 input enable. +#define AM_REG_GPIO_CFGE_GPIO34INCFG_S 8 +#define AM_REG_GPIO_CFGE_GPIO34INCFG_M 0x00000100 +#define AM_REG_GPIO_CFGE_GPIO34INCFG(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_CFGE_GPIO34INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO34INCFG_RDZERO 0x00000100 + +// GPIO33 interrupt direction. +#define AM_REG_GPIO_CFGE_GPIO33INTD_S 7 +#define AM_REG_GPIO_CFGE_GPIO33INTD_M 0x00000080 +#define AM_REG_GPIO_CFGE_GPIO33INTD(n) (((uint32_t)(n) << 7) & 0x00000080) +#define AM_REG_GPIO_CFGE_GPIO33INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO33INTD_INTHL 0x00000080 + +// GPIO33 output configuration. +#define AM_REG_GPIO_CFGE_GPIO33OUTCFG_S 5 +#define AM_REG_GPIO_CFGE_GPIO33OUTCFG_M 0x00000060 +#define AM_REG_GPIO_CFGE_GPIO33OUTCFG(n) (((uint32_t)(n) << 5) & 0x00000060) +#define AM_REG_GPIO_CFGE_GPIO33OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO33OUTCFG_PUSHPULL 0x00000020 +#define AM_REG_GPIO_CFGE_GPIO33OUTCFG_OD 0x00000040 +#define AM_REG_GPIO_CFGE_GPIO33OUTCFG_TS 0x00000060 + +// GPIO33 input enable. +#define AM_REG_GPIO_CFGE_GPIO33INCFG_S 4 +#define AM_REG_GPIO_CFGE_GPIO33INCFG_M 0x00000010 +#define AM_REG_GPIO_CFGE_GPIO33INCFG(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_CFGE_GPIO33INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO33INCFG_RDZERO 0x00000010 + +// GPIO32 interrupt direction. +#define AM_REG_GPIO_CFGE_GPIO32INTD_S 3 +#define AM_REG_GPIO_CFGE_GPIO32INTD_M 0x00000008 +#define AM_REG_GPIO_CFGE_GPIO32INTD(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_GPIO_CFGE_GPIO32INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO32INTD_INTHL 0x00000008 + +// GPIO32 output configuration. +#define AM_REG_GPIO_CFGE_GPIO32OUTCFG_S 1 +#define AM_REG_GPIO_CFGE_GPIO32OUTCFG_M 0x00000006 +#define AM_REG_GPIO_CFGE_GPIO32OUTCFG(n) (((uint32_t)(n) << 1) & 0x00000006) +#define AM_REG_GPIO_CFGE_GPIO32OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO32OUTCFG_PUSHPULL 0x00000002 +#define AM_REG_GPIO_CFGE_GPIO32OUTCFG_OD 0x00000004 +#define AM_REG_GPIO_CFGE_GPIO32OUTCFG_TS 0x00000006 + +// GPIO32 input enable. +#define AM_REG_GPIO_CFGE_GPIO32INCFG_S 0 +#define AM_REG_GPIO_CFGE_GPIO32INCFG_M 0x00000001 +#define AM_REG_GPIO_CFGE_GPIO32INCFG(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_CFGE_GPIO32INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGE_GPIO32INCFG_RDZERO 0x00000001 + +//***************************************************************************** +// +// GPIO_CFGF - GPIO Configuration Register F +// +//***************************************************************************** +// GPIO47 interrupt direction. +#define AM_REG_GPIO_CFGF_GPIO47INTD_S 31 +#define AM_REG_GPIO_CFGF_GPIO47INTD_M 0x80000000 +#define AM_REG_GPIO_CFGF_GPIO47INTD(n) (((uint32_t)(n) << 31) & 0x80000000) +#define AM_REG_GPIO_CFGF_GPIO47INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO47INTD_INTHL 0x80000000 + +// GPIO47 output configuration. +#define AM_REG_GPIO_CFGF_GPIO47OUTCFG_S 29 +#define AM_REG_GPIO_CFGF_GPIO47OUTCFG_M 0x60000000 +#define AM_REG_GPIO_CFGF_GPIO47OUTCFG(n) (((uint32_t)(n) << 29) & 0x60000000) +#define AM_REG_GPIO_CFGF_GPIO47OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO47OUTCFG_PUSHPULL 0x20000000 +#define AM_REG_GPIO_CFGF_GPIO47OUTCFG_OD 0x40000000 +#define AM_REG_GPIO_CFGF_GPIO47OUTCFG_TS 0x60000000 + +// GPIO47 input enable. +#define AM_REG_GPIO_CFGF_GPIO47INCFG_S 28 +#define AM_REG_GPIO_CFGF_GPIO47INCFG_M 0x10000000 +#define AM_REG_GPIO_CFGF_GPIO47INCFG(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_GPIO_CFGF_GPIO47INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO47INCFG_RDZERO 0x10000000 + +// GPIO46 interrupt direction. +#define AM_REG_GPIO_CFGF_GPIO46INTD_S 27 +#define AM_REG_GPIO_CFGF_GPIO46INTD_M 0x08000000 +#define AM_REG_GPIO_CFGF_GPIO46INTD(n) (((uint32_t)(n) << 27) & 0x08000000) +#define AM_REG_GPIO_CFGF_GPIO46INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO46INTD_INTHL 0x08000000 + +// GPIO46 output configuration. +#define AM_REG_GPIO_CFGF_GPIO46OUTCFG_S 25 +#define AM_REG_GPIO_CFGF_GPIO46OUTCFG_M 0x06000000 +#define AM_REG_GPIO_CFGF_GPIO46OUTCFG(n) (((uint32_t)(n) << 25) & 0x06000000) +#define AM_REG_GPIO_CFGF_GPIO46OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO46OUTCFG_PUSHPULL 0x02000000 +#define AM_REG_GPIO_CFGF_GPIO46OUTCFG_OD 0x04000000 +#define AM_REG_GPIO_CFGF_GPIO46OUTCFG_TS 0x06000000 + +// GPIO46 input enable. +#define AM_REG_GPIO_CFGF_GPIO46INCFG_S 24 +#define AM_REG_GPIO_CFGF_GPIO46INCFG_M 0x01000000 +#define AM_REG_GPIO_CFGF_GPIO46INCFG(n) (((uint32_t)(n) << 24) & 0x01000000) +#define AM_REG_GPIO_CFGF_GPIO46INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO46INCFG_RDZERO 0x01000000 + +// GPIO45 interrupt direction. +#define AM_REG_GPIO_CFGF_GPIO45INTD_S 23 +#define AM_REG_GPIO_CFGF_GPIO45INTD_M 0x00800000 +#define AM_REG_GPIO_CFGF_GPIO45INTD(n) (((uint32_t)(n) << 23) & 0x00800000) +#define AM_REG_GPIO_CFGF_GPIO45INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO45INTD_INTHL 0x00800000 + +// GPIO45 output configuration. +#define AM_REG_GPIO_CFGF_GPIO45OUTCFG_S 21 +#define AM_REG_GPIO_CFGF_GPIO45OUTCFG_M 0x00600000 +#define AM_REG_GPIO_CFGF_GPIO45OUTCFG(n) (((uint32_t)(n) << 21) & 0x00600000) +#define AM_REG_GPIO_CFGF_GPIO45OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO45OUTCFG_PUSHPULL 0x00200000 +#define AM_REG_GPIO_CFGF_GPIO45OUTCFG_OD 0x00400000 +#define AM_REG_GPIO_CFGF_GPIO45OUTCFG_TS 0x00600000 + +// GPIO45 input enable. +#define AM_REG_GPIO_CFGF_GPIO45INCFG_S 20 +#define AM_REG_GPIO_CFGF_GPIO45INCFG_M 0x00100000 +#define AM_REG_GPIO_CFGF_GPIO45INCFG(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_GPIO_CFGF_GPIO45INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO45INCFG_RDZERO 0x00100000 + +// GPIO44 interrupt direction. +#define AM_REG_GPIO_CFGF_GPIO44INTD_S 19 +#define AM_REG_GPIO_CFGF_GPIO44INTD_M 0x00080000 +#define AM_REG_GPIO_CFGF_GPIO44INTD(n) (((uint32_t)(n) << 19) & 0x00080000) +#define AM_REG_GPIO_CFGF_GPIO44INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO44INTD_INTHL 0x00080000 + +// GPIO44 output configuration. +#define AM_REG_GPIO_CFGF_GPIO44OUTCFG_S 17 +#define AM_REG_GPIO_CFGF_GPIO44OUTCFG_M 0x00060000 +#define AM_REG_GPIO_CFGF_GPIO44OUTCFG(n) (((uint32_t)(n) << 17) & 0x00060000) +#define AM_REG_GPIO_CFGF_GPIO44OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO44OUTCFG_PUSHPULL 0x00020000 +#define AM_REG_GPIO_CFGF_GPIO44OUTCFG_OD 0x00040000 +#define AM_REG_GPIO_CFGF_GPIO44OUTCFG_TS 0x00060000 + +// GPIO44 input enable. +#define AM_REG_GPIO_CFGF_GPIO44INCFG_S 16 +#define AM_REG_GPIO_CFGF_GPIO44INCFG_M 0x00010000 +#define AM_REG_GPIO_CFGF_GPIO44INCFG(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_GPIO_CFGF_GPIO44INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO44INCFG_RDZERO 0x00010000 + +// GPIO43 interrupt direction. +#define AM_REG_GPIO_CFGF_GPIO43INTD_S 15 +#define AM_REG_GPIO_CFGF_GPIO43INTD_M 0x00008000 +#define AM_REG_GPIO_CFGF_GPIO43INTD(n) (((uint32_t)(n) << 15) & 0x00008000) +#define AM_REG_GPIO_CFGF_GPIO43INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO43INTD_INTHL 0x00008000 + +// GPIO43 output configuration. +#define AM_REG_GPIO_CFGF_GPIO43OUTCFG_S 13 +#define AM_REG_GPIO_CFGF_GPIO43OUTCFG_M 0x00006000 +#define AM_REG_GPIO_CFGF_GPIO43OUTCFG(n) (((uint32_t)(n) << 13) & 0x00006000) +#define AM_REG_GPIO_CFGF_GPIO43OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO43OUTCFG_PUSHPULL 0x00002000 +#define AM_REG_GPIO_CFGF_GPIO43OUTCFG_OD 0x00004000 +#define AM_REG_GPIO_CFGF_GPIO43OUTCFG_TS 0x00006000 + +// GPIO43 input enable. +#define AM_REG_GPIO_CFGF_GPIO43INCFG_S 12 +#define AM_REG_GPIO_CFGF_GPIO43INCFG_M 0x00001000 +#define AM_REG_GPIO_CFGF_GPIO43INCFG(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_CFGF_GPIO43INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO43INCFG_RDZERO 0x00001000 + +// GPIO42 interrupt direction. +#define AM_REG_GPIO_CFGF_GPIO42INTD_S 11 +#define AM_REG_GPIO_CFGF_GPIO42INTD_M 0x00000800 +#define AM_REG_GPIO_CFGF_GPIO42INTD(n) (((uint32_t)(n) << 11) & 0x00000800) +#define AM_REG_GPIO_CFGF_GPIO42INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO42INTD_INTHL 0x00000800 + +// GPIO42 output configuration. +#define AM_REG_GPIO_CFGF_GPIO42OUTCFG_S 9 +#define AM_REG_GPIO_CFGF_GPIO42OUTCFG_M 0x00000600 +#define AM_REG_GPIO_CFGF_GPIO42OUTCFG(n) (((uint32_t)(n) << 9) & 0x00000600) +#define AM_REG_GPIO_CFGF_GPIO42OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO42OUTCFG_PUSHPULL 0x00000200 +#define AM_REG_GPIO_CFGF_GPIO42OUTCFG_OD 0x00000400 +#define AM_REG_GPIO_CFGF_GPIO42OUTCFG_TS 0x00000600 + +// GPIO42 input enable. +#define AM_REG_GPIO_CFGF_GPIO42INCFG_S 8 +#define AM_REG_GPIO_CFGF_GPIO42INCFG_M 0x00000100 +#define AM_REG_GPIO_CFGF_GPIO42INCFG(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_GPIO_CFGF_GPIO42INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO42INCFG_RDZERO 0x00000100 + +// GPIO41 interrupt direction. +#define AM_REG_GPIO_CFGF_GPIO41INTD_S 7 +#define AM_REG_GPIO_CFGF_GPIO41INTD_M 0x00000080 +#define AM_REG_GPIO_CFGF_GPIO41INTD(n) (((uint32_t)(n) << 7) & 0x00000080) +#define AM_REG_GPIO_CFGF_GPIO41INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO41INTD_INTHL 0x00000080 + +// GPIO41 output configuration. +#define AM_REG_GPIO_CFGF_GPIO41OUTCFG_S 5 +#define AM_REG_GPIO_CFGF_GPIO41OUTCFG_M 0x00000060 +#define AM_REG_GPIO_CFGF_GPIO41OUTCFG(n) (((uint32_t)(n) << 5) & 0x00000060) +#define AM_REG_GPIO_CFGF_GPIO41OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO41OUTCFG_PUSHPULL 0x00000020 +#define AM_REG_GPIO_CFGF_GPIO41OUTCFG_OD 0x00000040 +#define AM_REG_GPIO_CFGF_GPIO41OUTCFG_TS 0x00000060 + +// GPIO41 input enable. +#define AM_REG_GPIO_CFGF_GPIO41INCFG_S 4 +#define AM_REG_GPIO_CFGF_GPIO41INCFG_M 0x00000010 +#define AM_REG_GPIO_CFGF_GPIO41INCFG(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_CFGF_GPIO41INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO41INCFG_RDZERO 0x00000010 + +// GPIO40 interrupt direction. +#define AM_REG_GPIO_CFGF_GPIO40INTD_S 3 +#define AM_REG_GPIO_CFGF_GPIO40INTD_M 0x00000008 +#define AM_REG_GPIO_CFGF_GPIO40INTD(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_GPIO_CFGF_GPIO40INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO40INTD_INTHL 0x00000008 + +// GPIO40 output configuration. +#define AM_REG_GPIO_CFGF_GPIO40OUTCFG_S 1 +#define AM_REG_GPIO_CFGF_GPIO40OUTCFG_M 0x00000006 +#define AM_REG_GPIO_CFGF_GPIO40OUTCFG(n) (((uint32_t)(n) << 1) & 0x00000006) +#define AM_REG_GPIO_CFGF_GPIO40OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO40OUTCFG_PUSHPULL 0x00000002 +#define AM_REG_GPIO_CFGF_GPIO40OUTCFG_OD 0x00000004 +#define AM_REG_GPIO_CFGF_GPIO40OUTCFG_TS 0x00000006 + +// GPIO40 input enable. +#define AM_REG_GPIO_CFGF_GPIO40INCFG_S 0 +#define AM_REG_GPIO_CFGF_GPIO40INCFG_M 0x00000001 +#define AM_REG_GPIO_CFGF_GPIO40INCFG(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_CFGF_GPIO40INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGF_GPIO40INCFG_RDZERO 0x00000001 + +//***************************************************************************** +// +// GPIO_CFGG - GPIO Configuration Register G +// +//***************************************************************************** +// GPIO49 interrupt direction. +#define AM_REG_GPIO_CFGG_GPIO49INTD_S 7 +#define AM_REG_GPIO_CFGG_GPIO49INTD_M 0x00000080 +#define AM_REG_GPIO_CFGG_GPIO49INTD(n) (((uint32_t)(n) << 7) & 0x00000080) +#define AM_REG_GPIO_CFGG_GPIO49INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGG_GPIO49INTD_INTHL 0x00000080 + +// GPIO49 output configuration. +#define AM_REG_GPIO_CFGG_GPIO49OUTCFG_S 5 +#define AM_REG_GPIO_CFGG_GPIO49OUTCFG_M 0x00000060 +#define AM_REG_GPIO_CFGG_GPIO49OUTCFG(n) (((uint32_t)(n) << 5) & 0x00000060) +#define AM_REG_GPIO_CFGG_GPIO49OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGG_GPIO49OUTCFG_PUSHPULL 0x00000020 +#define AM_REG_GPIO_CFGG_GPIO49OUTCFG_OD 0x00000040 +#define AM_REG_GPIO_CFGG_GPIO49OUTCFG_TS 0x00000060 + +// GPIO49 input enable. +#define AM_REG_GPIO_CFGG_GPIO49INCFG_S 4 +#define AM_REG_GPIO_CFGG_GPIO49INCFG_M 0x00000010 +#define AM_REG_GPIO_CFGG_GPIO49INCFG(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_CFGG_GPIO49INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGG_GPIO49INCFG_RDZERO 0x00000010 + +// GPIO48 interrupt direction. +#define AM_REG_GPIO_CFGG_GPIO48INTD_S 3 +#define AM_REG_GPIO_CFGG_GPIO48INTD_M 0x00000008 +#define AM_REG_GPIO_CFGG_GPIO48INTD(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_GPIO_CFGG_GPIO48INTD_INTLH 0x00000000 +#define AM_REG_GPIO_CFGG_GPIO48INTD_INTHL 0x00000008 + +// GPIO48 output configuration. +#define AM_REG_GPIO_CFGG_GPIO48OUTCFG_S 1 +#define AM_REG_GPIO_CFGG_GPIO48OUTCFG_M 0x00000006 +#define AM_REG_GPIO_CFGG_GPIO48OUTCFG(n) (((uint32_t)(n) << 1) & 0x00000006) +#define AM_REG_GPIO_CFGG_GPIO48OUTCFG_DIS 0x00000000 +#define AM_REG_GPIO_CFGG_GPIO48OUTCFG_PUSHPULL 0x00000002 +#define AM_REG_GPIO_CFGG_GPIO48OUTCFG_OD 0x00000004 +#define AM_REG_GPIO_CFGG_GPIO48OUTCFG_TS 0x00000006 + +// GPIO48 input enable. +#define AM_REG_GPIO_CFGG_GPIO48INCFG_S 0 +#define AM_REG_GPIO_CFGG_GPIO48INCFG_M 0x00000001 +#define AM_REG_GPIO_CFGG_GPIO48INCFG(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_GPIO_CFGG_GPIO48INCFG_READ 0x00000000 +#define AM_REG_GPIO_CFGG_GPIO48INCFG_RDZERO 0x00000001 + +//***************************************************************************** +// +// GPIO_RDA - GPIO Input Register A +// +//***************************************************************************** +// GPIO31-0 read data. +#define AM_REG_GPIO_RDA_RDA_S 0 +#define AM_REG_GPIO_RDA_RDA_M 0xFFFFFFFF +#define AM_REG_GPIO_RDA_RDA(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// GPIO_RDB - GPIO Input Register B +// +//***************************************************************************** +// GPIO49-32 read data. +#define AM_REG_GPIO_RDB_RDB_S 0 +#define AM_REG_GPIO_RDB_RDB_M 0x0003FFFF +#define AM_REG_GPIO_RDB_RDB(n) (((uint32_t)(n) << 0) & 0x0003FFFF) + +//***************************************************************************** +// +// GPIO_WTA - GPIO Output Register A +// +//***************************************************************************** +// GPIO31-0 write data. +#define AM_REG_GPIO_WTA_WTA_S 0 +#define AM_REG_GPIO_WTA_WTA_M 0xFFFFFFFF +#define AM_REG_GPIO_WTA_WTA(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// GPIO_WTB - GPIO Output Register B +// +//***************************************************************************** +// GPIO49-32 write data. +#define AM_REG_GPIO_WTB_WTB_S 0 +#define AM_REG_GPIO_WTB_WTB_M 0x0003FFFF +#define AM_REG_GPIO_WTB_WTB(n) (((uint32_t)(n) << 0) & 0x0003FFFF) + +//***************************************************************************** +// +// GPIO_WTSA - GPIO Output Register A Set +// +//***************************************************************************** +// Set the GPIO31-0 write data. +#define AM_REG_GPIO_WTSA_WTSA_S 0 +#define AM_REG_GPIO_WTSA_WTSA_M 0xFFFFFFFF +#define AM_REG_GPIO_WTSA_WTSA(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// GPIO_WTSB - GPIO Output Register B Set +// +//***************************************************************************** +// Set the GPIO49-32 write data. +#define AM_REG_GPIO_WTSB_WTSB_S 0 +#define AM_REG_GPIO_WTSB_WTSB_M 0x0003FFFF +#define AM_REG_GPIO_WTSB_WTSB(n) (((uint32_t)(n) << 0) & 0x0003FFFF) + +//***************************************************************************** +// +// GPIO_WTCA - GPIO Output Register A Clear +// +//***************************************************************************** +// Clear the GPIO31-0 write data. +#define AM_REG_GPIO_WTCA_WTCA_S 0 +#define AM_REG_GPIO_WTCA_WTCA_M 0xFFFFFFFF +#define AM_REG_GPIO_WTCA_WTCA(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// GPIO_WTCB - GPIO Output Register B Clear +// +//***************************************************************************** +// Clear the GPIO49-32 write data. +#define AM_REG_GPIO_WTCB_WTCB_S 0 +#define AM_REG_GPIO_WTCB_WTCB_M 0x0003FFFF +#define AM_REG_GPIO_WTCB_WTCB(n) (((uint32_t)(n) << 0) & 0x0003FFFF) + +//***************************************************************************** +// +// GPIO_ENA - GPIO Enable Register A +// +//***************************************************************************** +// GPIO31-0 output enables +#define AM_REG_GPIO_ENA_ENA_S 0 +#define AM_REG_GPIO_ENA_ENA_M 0xFFFFFFFF +#define AM_REG_GPIO_ENA_ENA(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// GPIO_ENB - GPIO Enable Register B +// +//***************************************************************************** +// GPIO49-32 output enables +#define AM_REG_GPIO_ENB_ENB_S 0 +#define AM_REG_GPIO_ENB_ENB_M 0x0003FFFF +#define AM_REG_GPIO_ENB_ENB(n) (((uint32_t)(n) << 0) & 0x0003FFFF) + +//***************************************************************************** +// +// GPIO_ENSA - GPIO Enable Register A Set +// +//***************************************************************************** +// Set the GPIO31-0 output enables +#define AM_REG_GPIO_ENSA_ENSA_S 0 +#define AM_REG_GPIO_ENSA_ENSA_M 0xFFFFFFFF +#define AM_REG_GPIO_ENSA_ENSA(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// GPIO_ENSB - GPIO Enable Register B Set +// +//***************************************************************************** +// Set the GPIO49-32 output enables +#define AM_REG_GPIO_ENSB_ENSB_S 0 +#define AM_REG_GPIO_ENSB_ENSB_M 0x0003FFFF +#define AM_REG_GPIO_ENSB_ENSB(n) (((uint32_t)(n) << 0) & 0x0003FFFF) + +//***************************************************************************** +// +// GPIO_ENCA - GPIO Enable Register A Clear +// +//***************************************************************************** +// Clear the GPIO31-0 output enables +#define AM_REG_GPIO_ENCA_ENCA_S 0 +#define AM_REG_GPIO_ENCA_ENCA_M 0xFFFFFFFF +#define AM_REG_GPIO_ENCA_ENCA(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// GPIO_ENCB - GPIO Enable Register B Clear +// +//***************************************************************************** +// Clear the GPIO49-32 output enables +#define AM_REG_GPIO_ENCB_ENCB_S 0 +#define AM_REG_GPIO_ENCB_ENCB_M 0x0003FFFF +#define AM_REG_GPIO_ENCB_ENCB(n) (((uint32_t)(n) << 0) & 0x0003FFFF) + +//***************************************************************************** +// +// GPIO_STMRCAP - STIMER Capture Control +// +//***************************************************************************** +// STIMER Capture 3 Polarity. +#define AM_REG_GPIO_STMRCAP_STPOL3_S 30 +#define AM_REG_GPIO_STMRCAP_STPOL3_M 0x40000000 +#define AM_REG_GPIO_STMRCAP_STPOL3(n) (((uint32_t)(n) << 30) & 0x40000000) +#define AM_REG_GPIO_STMRCAP_STPOL3_CAPLH 0x00000000 +#define AM_REG_GPIO_STMRCAP_STPOL3_CAPHL 0x40000000 + +// STIMER Capture 3 Select. +#define AM_REG_GPIO_STMRCAP_STSEL3_S 24 +#define AM_REG_GPIO_STMRCAP_STSEL3_M 0x3F000000 +#define AM_REG_GPIO_STMRCAP_STSEL3(n) (((uint32_t)(n) << 24) & 0x3F000000) + +// STIMER Capture 2 Polarity. +#define AM_REG_GPIO_STMRCAP_STPOL2_S 22 +#define AM_REG_GPIO_STMRCAP_STPOL2_M 0x00400000 +#define AM_REG_GPIO_STMRCAP_STPOL2(n) (((uint32_t)(n) << 22) & 0x00400000) +#define AM_REG_GPIO_STMRCAP_STPOL2_CAPLH 0x00000000 +#define AM_REG_GPIO_STMRCAP_STPOL2_CAPHL 0x00400000 + +// STIMER Capture 2 Select. +#define AM_REG_GPIO_STMRCAP_STSEL2_S 16 +#define AM_REG_GPIO_STMRCAP_STSEL2_M 0x003F0000 +#define AM_REG_GPIO_STMRCAP_STSEL2(n) (((uint32_t)(n) << 16) & 0x003F0000) + +// STIMER Capture 1 Polarity. +#define AM_REG_GPIO_STMRCAP_STPOL1_S 14 +#define AM_REG_GPIO_STMRCAP_STPOL1_M 0x00004000 +#define AM_REG_GPIO_STMRCAP_STPOL1(n) (((uint32_t)(n) << 14) & 0x00004000) +#define AM_REG_GPIO_STMRCAP_STPOL1_CAPLH 0x00000000 +#define AM_REG_GPIO_STMRCAP_STPOL1_CAPHL 0x00004000 + +// STIMER Capture 1 Select. +#define AM_REG_GPIO_STMRCAP_STSEL1_S 8 +#define AM_REG_GPIO_STMRCAP_STSEL1_M 0x00003F00 +#define AM_REG_GPIO_STMRCAP_STSEL1(n) (((uint32_t)(n) << 8) & 0x00003F00) + +// STIMER Capture 0 Polarity. +#define AM_REG_GPIO_STMRCAP_STPOL0_S 6 +#define AM_REG_GPIO_STMRCAP_STPOL0_M 0x00000040 +#define AM_REG_GPIO_STMRCAP_STPOL0(n) (((uint32_t)(n) << 6) & 0x00000040) +#define AM_REG_GPIO_STMRCAP_STPOL0_CAPLH 0x00000000 +#define AM_REG_GPIO_STMRCAP_STPOL0_CAPHL 0x00000040 + +// STIMER Capture 0 Select. +#define AM_REG_GPIO_STMRCAP_STSEL0_S 0 +#define AM_REG_GPIO_STMRCAP_STSEL0_M 0x0000003F +#define AM_REG_GPIO_STMRCAP_STSEL0(n) (((uint32_t)(n) << 0) & 0x0000003F) + +//***************************************************************************** +// +// GPIO_IOM0IRQ - IOM0 Flow Control IRQ Select +// +//***************************************************************************** +// IOMSTR0 IRQ pad select. +#define AM_REG_GPIO_IOM0IRQ_IOM0IRQ_S 0 +#define AM_REG_GPIO_IOM0IRQ_IOM0IRQ_M 0x0000003F +#define AM_REG_GPIO_IOM0IRQ_IOM0IRQ(n) (((uint32_t)(n) << 0) & 0x0000003F) + +//***************************************************************************** +// +// GPIO_IOM1IRQ - IOM1 Flow Control IRQ Select +// +//***************************************************************************** +// IOMSTR1 IRQ pad select. +#define AM_REG_GPIO_IOM1IRQ_IOM1IRQ_S 0 +#define AM_REG_GPIO_IOM1IRQ_IOM1IRQ_M 0x0000003F +#define AM_REG_GPIO_IOM1IRQ_IOM1IRQ(n) (((uint32_t)(n) << 0) & 0x0000003F) + +//***************************************************************************** +// +// GPIO_IOM2IRQ - IOM2 Flow Control IRQ Select +// +//***************************************************************************** +// IOMSTR2 IRQ pad select. +#define AM_REG_GPIO_IOM2IRQ_IOM2IRQ_S 0 +#define AM_REG_GPIO_IOM2IRQ_IOM2IRQ_M 0x0000003F +#define AM_REG_GPIO_IOM2IRQ_IOM2IRQ(n) (((uint32_t)(n) << 0) & 0x0000003F) + +//***************************************************************************** +// +// GPIO_IOM3IRQ - IOM3 Flow Control IRQ Select +// +//***************************************************************************** +// IOMSTR3 IRQ pad select. +#define AM_REG_GPIO_IOM3IRQ_IOM3IRQ_S 0 +#define AM_REG_GPIO_IOM3IRQ_IOM3IRQ_M 0x0000003F +#define AM_REG_GPIO_IOM3IRQ_IOM3IRQ(n) (((uint32_t)(n) << 0) & 0x0000003F) + +//***************************************************************************** +// +// GPIO_IOM4IRQ - IOM4 Flow Control IRQ Select +// +//***************************************************************************** +// IOMSTR4 IRQ pad select. +#define AM_REG_GPIO_IOM4IRQ_IOM4IRQ_S 0 +#define AM_REG_GPIO_IOM4IRQ_IOM4IRQ_M 0x0000003F +#define AM_REG_GPIO_IOM4IRQ_IOM4IRQ(n) (((uint32_t)(n) << 0) & 0x0000003F) + +//***************************************************************************** +// +// GPIO_IOM5IRQ - IOM5 Flow Control IRQ Select +// +//***************************************************************************** +// IOMSTR5 IRQ pad select. +#define AM_REG_GPIO_IOM5IRQ_IOM5IRQ_S 0 +#define AM_REG_GPIO_IOM5IRQ_IOM5IRQ_M 0x0000003F +#define AM_REG_GPIO_IOM5IRQ_IOM5IRQ(n) (((uint32_t)(n) << 0) & 0x0000003F) + +//***************************************************************************** +// +// GPIO_LOOPBACK - IOM to IOS Loopback Control +// +//***************************************************************************** +// IOM to IOS loopback control. +#define AM_REG_GPIO_LOOPBACK_LOOPBACK_S 0 +#define AM_REG_GPIO_LOOPBACK_LOOPBACK_M 0x00000007 +#define AM_REG_GPIO_LOOPBACK_LOOPBACK(n) (((uint32_t)(n) << 0) & 0x00000007) +#define AM_REG_GPIO_LOOPBACK_LOOPBACK_LOOP0 0x00000000 +#define AM_REG_GPIO_LOOPBACK_LOOPBACK_LOOP1 0x00000001 +#define AM_REG_GPIO_LOOPBACK_LOOPBACK_LOOP2 0x00000002 +#define AM_REG_GPIO_LOOPBACK_LOOPBACK_LOOP3 0x00000003 +#define AM_REG_GPIO_LOOPBACK_LOOPBACK_LOOP4 0x00000004 +#define AM_REG_GPIO_LOOPBACK_LOOPBACK_LOOP5 0x00000005 +#define AM_REG_GPIO_LOOPBACK_LOOPBACK_LOOPNONE 0x00000006 + +//***************************************************************************** +// +// GPIO_GPIOOBS - GPIO Observation Mode Sample register +// +//***************************************************************************** +// Sample of the data output on the GPIO observation port. May have async +// sampling issues, as the data is not synronized to the read operation. +// Intended for debug purposes only +#define AM_REG_GPIO_GPIOOBS_OBS_DATA_S 0 +#define AM_REG_GPIO_GPIOOBS_OBS_DATA_M 0x0000FFFF +#define AM_REG_GPIO_GPIOOBS_OBS_DATA(n) (((uint32_t)(n) << 0) & 0x0000FFFF) + +//***************************************************************************** +// +// GPIO_ALTPADCFGA - Alternate Pad Configuration reg0 (Pads 3,2,1,0) +// +//***************************************************************************** +// Pad 3 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGA_PAD3_SR_S 28 +#define AM_REG_GPIO_ALTPADCFGA_PAD3_SR_M 0x10000000 +#define AM_REG_GPIO_ALTPADCFGA_PAD3_SR(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_GPIO_ALTPADCFGA_PAD3_SR_SR_EN 0x10000000 + +// Pad 3 high order drive strength selection. Used in conjunction with +// PAD3STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGA_PAD3_DS1_S 24 +#define AM_REG_GPIO_ALTPADCFGA_PAD3_DS1_M 0x01000000 +#define AM_REG_GPIO_ALTPADCFGA_PAD3_DS1(n) (((uint32_t)(n) << 24) & 0x01000000) + +// Pad 2 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGA_PAD2_SR_S 20 +#define AM_REG_GPIO_ALTPADCFGA_PAD2_SR_M 0x00100000 +#define AM_REG_GPIO_ALTPADCFGA_PAD2_SR(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_GPIO_ALTPADCFGA_PAD2_SR_SR_EN 0x00100000 + +// Pad 2 high order drive strength selection. Used in conjunction with +// PAD2STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGA_PAD2_DS1_S 16 +#define AM_REG_GPIO_ALTPADCFGA_PAD2_DS1_M 0x00010000 +#define AM_REG_GPIO_ALTPADCFGA_PAD2_DS1(n) (((uint32_t)(n) << 16) & 0x00010000) + +// Pad 1 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGA_PAD1_SR_S 12 +#define AM_REG_GPIO_ALTPADCFGA_PAD1_SR_M 0x00001000 +#define AM_REG_GPIO_ALTPADCFGA_PAD1_SR(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_ALTPADCFGA_PAD1_SR_SR_EN 0x00001000 + +// Pad 1 high order drive strength selection. Used in conjunction with +// PAD1STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGA_PAD1_DS1_S 8 +#define AM_REG_GPIO_ALTPADCFGA_PAD1_DS1_M 0x00000100 +#define AM_REG_GPIO_ALTPADCFGA_PAD1_DS1(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Pad 0 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGA_PAD0_SR_S 4 +#define AM_REG_GPIO_ALTPADCFGA_PAD0_SR_M 0x00000010 +#define AM_REG_GPIO_ALTPADCFGA_PAD0_SR(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_ALTPADCFGA_PAD0_SR_SR_EN 0x00000010 + +// Pad 0 high order drive strength selection. Used in conjunction with +// PAD0STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGA_PAD0_DS1_S 0 +#define AM_REG_GPIO_ALTPADCFGA_PAD0_DS1_M 0x00000001 +#define AM_REG_GPIO_ALTPADCFGA_PAD0_DS1(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_ALTPADCFGB - Alternate Pad Configuration reg1 (Pads 7,6,5,4) +// +//***************************************************************************** +// Pad 7 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGB_PAD7_SR_S 28 +#define AM_REG_GPIO_ALTPADCFGB_PAD7_SR_M 0x10000000 +#define AM_REG_GPIO_ALTPADCFGB_PAD7_SR(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_GPIO_ALTPADCFGB_PAD7_SR_SR_EN 0x10000000 + +// Pad 7 high order drive strength selection. Used in conjunction with +// PAD7STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGB_PAD7_DS1_S 24 +#define AM_REG_GPIO_ALTPADCFGB_PAD7_DS1_M 0x01000000 +#define AM_REG_GPIO_ALTPADCFGB_PAD7_DS1(n) (((uint32_t)(n) << 24) & 0x01000000) + +// Pad 6 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGB_PAD6_SR_S 20 +#define AM_REG_GPIO_ALTPADCFGB_PAD6_SR_M 0x00100000 +#define AM_REG_GPIO_ALTPADCFGB_PAD6_SR(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_GPIO_ALTPADCFGB_PAD6_SR_SR_EN 0x00100000 + +// Pad 6 high order drive strength selection. Used in conjunction with +// PAD6STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGB_PAD6_DS1_S 16 +#define AM_REG_GPIO_ALTPADCFGB_PAD6_DS1_M 0x00010000 +#define AM_REG_GPIO_ALTPADCFGB_PAD6_DS1(n) (((uint32_t)(n) << 16) & 0x00010000) + +// Pad 5 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGB_PAD5_SR_S 12 +#define AM_REG_GPIO_ALTPADCFGB_PAD5_SR_M 0x00001000 +#define AM_REG_GPIO_ALTPADCFGB_PAD5_SR(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_ALTPADCFGB_PAD5_SR_SR_EN 0x00001000 + +// Pad 5 high order drive strength selection. Used in conjunction with +// PAD5STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGB_PAD5_DS1_S 8 +#define AM_REG_GPIO_ALTPADCFGB_PAD5_DS1_M 0x00000100 +#define AM_REG_GPIO_ALTPADCFGB_PAD5_DS1(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Pad 4 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGB_PAD4_SR_S 4 +#define AM_REG_GPIO_ALTPADCFGB_PAD4_SR_M 0x00000010 +#define AM_REG_GPIO_ALTPADCFGB_PAD4_SR(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_ALTPADCFGB_PAD4_SR_SR_EN 0x00000010 + +// Pad 4 high order drive strength selection. Used in conjunction with +// PAD4STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGB_PAD4_DS1_S 0 +#define AM_REG_GPIO_ALTPADCFGB_PAD4_DS1_M 0x00000001 +#define AM_REG_GPIO_ALTPADCFGB_PAD4_DS1(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_ALTPADCFGC - Alternate Pad Configuration reg2 (Pads 11,10,9,8) +// +//***************************************************************************** +// Pad 11 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGC_PAD11_SR_S 28 +#define AM_REG_GPIO_ALTPADCFGC_PAD11_SR_M 0x10000000 +#define AM_REG_GPIO_ALTPADCFGC_PAD11_SR(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_GPIO_ALTPADCFGC_PAD11_SR_SR_EN 0x10000000 + +// Pad 11 high order drive strength selection. Used in conjunction with +// PAD11STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGC_PAD11_DS1_S 24 +#define AM_REG_GPIO_ALTPADCFGC_PAD11_DS1_M 0x01000000 +#define AM_REG_GPIO_ALTPADCFGC_PAD11_DS1(n) (((uint32_t)(n) << 24) & 0x01000000) + +// Pad 10 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGC_PAD10_SR_S 20 +#define AM_REG_GPIO_ALTPADCFGC_PAD10_SR_M 0x00100000 +#define AM_REG_GPIO_ALTPADCFGC_PAD10_SR(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_GPIO_ALTPADCFGC_PAD10_SR_SR_EN 0x00100000 + +// Pad 10 high order drive strength selection. Used in conjunction with +// PAD10STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGC_PAD10_DS1_S 16 +#define AM_REG_GPIO_ALTPADCFGC_PAD10_DS1_M 0x00010000 +#define AM_REG_GPIO_ALTPADCFGC_PAD10_DS1(n) (((uint32_t)(n) << 16) & 0x00010000) + +// Pad 9 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGC_PAD9_SR_S 12 +#define AM_REG_GPIO_ALTPADCFGC_PAD9_SR_M 0x00001000 +#define AM_REG_GPIO_ALTPADCFGC_PAD9_SR(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_ALTPADCFGC_PAD9_SR_SR_EN 0x00001000 + +// Pad 9 high order drive strength selection. Used in conjunction with +// PAD9STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGC_PAD9_DS1_S 8 +#define AM_REG_GPIO_ALTPADCFGC_PAD9_DS1_M 0x00000100 +#define AM_REG_GPIO_ALTPADCFGC_PAD9_DS1(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Pad 8 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGC_PAD8_SR_S 4 +#define AM_REG_GPIO_ALTPADCFGC_PAD8_SR_M 0x00000010 +#define AM_REG_GPIO_ALTPADCFGC_PAD8_SR(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_ALTPADCFGC_PAD8_SR_SR_EN 0x00000010 + +// Pad 8 high order drive strength selection. Used in conjunction with +// PAD8STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGC_PAD8_DS1_S 0 +#define AM_REG_GPIO_ALTPADCFGC_PAD8_DS1_M 0x00000001 +#define AM_REG_GPIO_ALTPADCFGC_PAD8_DS1(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_ALTPADCFGD - Alternate Pad Configuration reg3 (Pads 15,14,13,12) +// +//***************************************************************************** +// Pad 15 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGD_PAD15_SR_S 28 +#define AM_REG_GPIO_ALTPADCFGD_PAD15_SR_M 0x10000000 +#define AM_REG_GPIO_ALTPADCFGD_PAD15_SR(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_GPIO_ALTPADCFGD_PAD15_SR_SR_EN 0x10000000 + +// Pad 15 high order drive strength selection. Used in conjunction with +// PAD15STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGD_PAD15_DS1_S 24 +#define AM_REG_GPIO_ALTPADCFGD_PAD15_DS1_M 0x01000000 +#define AM_REG_GPIO_ALTPADCFGD_PAD15_DS1(n) (((uint32_t)(n) << 24) & 0x01000000) + +// Pad 14 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGD_PAD14_SR_S 20 +#define AM_REG_GPIO_ALTPADCFGD_PAD14_SR_M 0x00100000 +#define AM_REG_GPIO_ALTPADCFGD_PAD14_SR(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_GPIO_ALTPADCFGD_PAD14_SR_SR_EN 0x00100000 + +// Pad 14 high order drive strength selection. Used in conjunction with +// PAD14STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGD_PAD14_DS1_S 16 +#define AM_REG_GPIO_ALTPADCFGD_PAD14_DS1_M 0x00010000 +#define AM_REG_GPIO_ALTPADCFGD_PAD14_DS1(n) (((uint32_t)(n) << 16) & 0x00010000) + +// Pad 13 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGD_PAD13_SR_S 12 +#define AM_REG_GPIO_ALTPADCFGD_PAD13_SR_M 0x00001000 +#define AM_REG_GPIO_ALTPADCFGD_PAD13_SR(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_ALTPADCFGD_PAD13_SR_SR_EN 0x00001000 + +// Pad 13 high order drive strength selection. Used in conjunction with +// PAD13STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGD_PAD13_DS1_S 8 +#define AM_REG_GPIO_ALTPADCFGD_PAD13_DS1_M 0x00000100 +#define AM_REG_GPIO_ALTPADCFGD_PAD13_DS1(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Pad 12 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGD_PAD12_SR_S 4 +#define AM_REG_GPIO_ALTPADCFGD_PAD12_SR_M 0x00000010 +#define AM_REG_GPIO_ALTPADCFGD_PAD12_SR(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_ALTPADCFGD_PAD12_SR_SR_EN 0x00000010 + +// Pad 12 high order drive strength selection. Used in conjunction with +// PAD12STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGD_PAD12_DS1_S 0 +#define AM_REG_GPIO_ALTPADCFGD_PAD12_DS1_M 0x00000001 +#define AM_REG_GPIO_ALTPADCFGD_PAD12_DS1(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_ALTPADCFGE - Alternate Pad Configuration reg4 (Pads 19,18,17,16) +// +//***************************************************************************** +// Pad 19 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGE_PAD19_SR_S 28 +#define AM_REG_GPIO_ALTPADCFGE_PAD19_SR_M 0x10000000 +#define AM_REG_GPIO_ALTPADCFGE_PAD19_SR(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_GPIO_ALTPADCFGE_PAD19_SR_SR_EN 0x10000000 + +// Pad 19 high order drive strength selection. Used in conjunction with +// PAD19STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGE_PAD19_DS1_S 24 +#define AM_REG_GPIO_ALTPADCFGE_PAD19_DS1_M 0x01000000 +#define AM_REG_GPIO_ALTPADCFGE_PAD19_DS1(n) (((uint32_t)(n) << 24) & 0x01000000) + +// Pad 18 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGE_PAD18_SR_S 20 +#define AM_REG_GPIO_ALTPADCFGE_PAD18_SR_M 0x00100000 +#define AM_REG_GPIO_ALTPADCFGE_PAD18_SR(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_GPIO_ALTPADCFGE_PAD18_SR_SR_EN 0x00100000 + +// Pad 18 high order drive strength selection. Used in conjunction with +// PAD18STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGE_PAD18_DS1_S 16 +#define AM_REG_GPIO_ALTPADCFGE_PAD18_DS1_M 0x00010000 +#define AM_REG_GPIO_ALTPADCFGE_PAD18_DS1(n) (((uint32_t)(n) << 16) & 0x00010000) + +// Pad 17 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGE_PAD17_SR_S 12 +#define AM_REG_GPIO_ALTPADCFGE_PAD17_SR_M 0x00001000 +#define AM_REG_GPIO_ALTPADCFGE_PAD17_SR(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_ALTPADCFGE_PAD17_SR_SR_EN 0x00001000 + +// Pad 17 high order drive strength selection. Used in conjunction with +// PAD17STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGE_PAD17_DS1_S 8 +#define AM_REG_GPIO_ALTPADCFGE_PAD17_DS1_M 0x00000100 +#define AM_REG_GPIO_ALTPADCFGE_PAD17_DS1(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Pad 16 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGE_PAD16_SR_S 4 +#define AM_REG_GPIO_ALTPADCFGE_PAD16_SR_M 0x00000010 +#define AM_REG_GPIO_ALTPADCFGE_PAD16_SR(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_ALTPADCFGE_PAD16_SR_SR_EN 0x00000010 + +// Pad 16 high order drive strength selection. Used in conjunction with +// PAD16STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGE_PAD16_DS1_S 0 +#define AM_REG_GPIO_ALTPADCFGE_PAD16_DS1_M 0x00000001 +#define AM_REG_GPIO_ALTPADCFGE_PAD16_DS1(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_ALTPADCFGF - Alternate Pad Configuration reg5 (Pads 23,22,21,20) +// +//***************************************************************************** +// Pad 23 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGF_PAD23_SR_S 28 +#define AM_REG_GPIO_ALTPADCFGF_PAD23_SR_M 0x10000000 +#define AM_REG_GPIO_ALTPADCFGF_PAD23_SR(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_GPIO_ALTPADCFGF_PAD23_SR_SR_EN 0x10000000 + +// Pad 23 high order drive strength selection. Used in conjunction with +// PAD23STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGF_PAD23_DS1_S 24 +#define AM_REG_GPIO_ALTPADCFGF_PAD23_DS1_M 0x01000000 +#define AM_REG_GPIO_ALTPADCFGF_PAD23_DS1(n) (((uint32_t)(n) << 24) & 0x01000000) + +// Pad 22 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGF_PAD22_SR_S 20 +#define AM_REG_GPIO_ALTPADCFGF_PAD22_SR_M 0x00100000 +#define AM_REG_GPIO_ALTPADCFGF_PAD22_SR(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_GPIO_ALTPADCFGF_PAD22_SR_SR_EN 0x00100000 + +// Pad 22 high order drive strength selection. Used in conjunction with +// PAD22STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGF_PAD22_DS1_S 16 +#define AM_REG_GPIO_ALTPADCFGF_PAD22_DS1_M 0x00010000 +#define AM_REG_GPIO_ALTPADCFGF_PAD22_DS1(n) (((uint32_t)(n) << 16) & 0x00010000) + +// Pad 21 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGF_PAD21_SR_S 12 +#define AM_REG_GPIO_ALTPADCFGF_PAD21_SR_M 0x00001000 +#define AM_REG_GPIO_ALTPADCFGF_PAD21_SR(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_ALTPADCFGF_PAD21_SR_SR_EN 0x00001000 + +// Pad 21 high order drive strength selection. Used in conjunction with +// PAD21STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGF_PAD21_DS1_S 8 +#define AM_REG_GPIO_ALTPADCFGF_PAD21_DS1_M 0x00000100 +#define AM_REG_GPIO_ALTPADCFGF_PAD21_DS1(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Pad 20 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGF_PAD20_SR_S 4 +#define AM_REG_GPIO_ALTPADCFGF_PAD20_SR_M 0x00000010 +#define AM_REG_GPIO_ALTPADCFGF_PAD20_SR(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_ALTPADCFGF_PAD20_SR_SR_EN 0x00000010 + +// Pad 20 high order drive strength selection. Used in conjunction with +// PAD20STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGF_PAD20_DS1_S 0 +#define AM_REG_GPIO_ALTPADCFGF_PAD20_DS1_M 0x00000001 +#define AM_REG_GPIO_ALTPADCFGF_PAD20_DS1(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_ALTPADCFGG - Alternate Pad Configuration reg6 (Pads 27,26,25,24) +// +//***************************************************************************** +// Pad 27 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGG_PAD27_SR_S 28 +#define AM_REG_GPIO_ALTPADCFGG_PAD27_SR_M 0x10000000 +#define AM_REG_GPIO_ALTPADCFGG_PAD27_SR(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_GPIO_ALTPADCFGG_PAD27_SR_SR_EN 0x10000000 + +// Pad 27 high order drive strength selection. Used in conjunction with +// PAD27STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGG_PAD27_DS1_S 24 +#define AM_REG_GPIO_ALTPADCFGG_PAD27_DS1_M 0x01000000 +#define AM_REG_GPIO_ALTPADCFGG_PAD27_DS1(n) (((uint32_t)(n) << 24) & 0x01000000) + +// Pad 26 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGG_PAD26_SR_S 20 +#define AM_REG_GPIO_ALTPADCFGG_PAD26_SR_M 0x00100000 +#define AM_REG_GPIO_ALTPADCFGG_PAD26_SR(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_GPIO_ALTPADCFGG_PAD26_SR_SR_EN 0x00100000 + +// Pad 26 high order drive strength selection. Used in conjunction with +// PAD26STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGG_PAD26_DS1_S 16 +#define AM_REG_GPIO_ALTPADCFGG_PAD26_DS1_M 0x00010000 +#define AM_REG_GPIO_ALTPADCFGG_PAD26_DS1(n) (((uint32_t)(n) << 16) & 0x00010000) + +// Pad 25 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGG_PAD25_SR_S 12 +#define AM_REG_GPIO_ALTPADCFGG_PAD25_SR_M 0x00001000 +#define AM_REG_GPIO_ALTPADCFGG_PAD25_SR(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_ALTPADCFGG_PAD25_SR_SR_EN 0x00001000 + +// Pad 25 high order drive strength selection. Used in conjunction with +// PAD25STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGG_PAD25_DS1_S 8 +#define AM_REG_GPIO_ALTPADCFGG_PAD25_DS1_M 0x00000100 +#define AM_REG_GPIO_ALTPADCFGG_PAD25_DS1(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Pad 24 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGG_PAD24_SR_S 4 +#define AM_REG_GPIO_ALTPADCFGG_PAD24_SR_M 0x00000010 +#define AM_REG_GPIO_ALTPADCFGG_PAD24_SR(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_ALTPADCFGG_PAD24_SR_SR_EN 0x00000010 + +// Pad 24 high order drive strength selection. Used in conjunction with +// PAD24STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGG_PAD24_DS1_S 0 +#define AM_REG_GPIO_ALTPADCFGG_PAD24_DS1_M 0x00000001 +#define AM_REG_GPIO_ALTPADCFGG_PAD24_DS1(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_ALTPADCFGH - Alternate Pad Configuration reg7 (Pads 31,30,29,28) +// +//***************************************************************************** +// Pad 31 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGH_PAD31_SR_S 28 +#define AM_REG_GPIO_ALTPADCFGH_PAD31_SR_M 0x10000000 +#define AM_REG_GPIO_ALTPADCFGH_PAD31_SR(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_GPIO_ALTPADCFGH_PAD31_SR_SR_EN 0x10000000 + +// Pad 31 high order drive strength selection. Used in conjunction with +// PAD31STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGH_PAD31_DS1_S 24 +#define AM_REG_GPIO_ALTPADCFGH_PAD31_DS1_M 0x01000000 +#define AM_REG_GPIO_ALTPADCFGH_PAD31_DS1(n) (((uint32_t)(n) << 24) & 0x01000000) + +// Pad 30 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGH_PAD30_SR_S 20 +#define AM_REG_GPIO_ALTPADCFGH_PAD30_SR_M 0x00100000 +#define AM_REG_GPIO_ALTPADCFGH_PAD30_SR(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_GPIO_ALTPADCFGH_PAD30_SR_SR_EN 0x00100000 + +// Pad 30 high order drive strength selection. Used in conjunction with +// PAD30STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGH_PAD30_DS1_S 16 +#define AM_REG_GPIO_ALTPADCFGH_PAD30_DS1_M 0x00010000 +#define AM_REG_GPIO_ALTPADCFGH_PAD30_DS1(n) (((uint32_t)(n) << 16) & 0x00010000) + +// Pad 29 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGH_PAD29_SR_S 12 +#define AM_REG_GPIO_ALTPADCFGH_PAD29_SR_M 0x00001000 +#define AM_REG_GPIO_ALTPADCFGH_PAD29_SR(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_ALTPADCFGH_PAD29_SR_SR_EN 0x00001000 + +// Pad 29 high order drive strength selection. Used in conjunction with +// PAD29STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGH_PAD29_DS1_S 8 +#define AM_REG_GPIO_ALTPADCFGH_PAD29_DS1_M 0x00000100 +#define AM_REG_GPIO_ALTPADCFGH_PAD29_DS1(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Pad 28 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGH_PAD28_SR_S 4 +#define AM_REG_GPIO_ALTPADCFGH_PAD28_SR_M 0x00000010 +#define AM_REG_GPIO_ALTPADCFGH_PAD28_SR(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_ALTPADCFGH_PAD28_SR_SR_EN 0x00000010 + +// Pad 28 high order drive strength selection. Used in conjunction with +// PAD28STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGH_PAD28_DS1_S 0 +#define AM_REG_GPIO_ALTPADCFGH_PAD28_DS1_M 0x00000001 +#define AM_REG_GPIO_ALTPADCFGH_PAD28_DS1(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_ALTPADCFGI - Alternate Pad Configuration reg8 (Pads 35,34,33,32) +// +//***************************************************************************** +// Pad 35 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGI_PAD35_SR_S 28 +#define AM_REG_GPIO_ALTPADCFGI_PAD35_SR_M 0x10000000 +#define AM_REG_GPIO_ALTPADCFGI_PAD35_SR(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_GPIO_ALTPADCFGI_PAD35_SR_SR_EN 0x10000000 + +// Pad 35 high order drive strength selection. Used in conjunction with +// PAD35STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGI_PAD35_DS1_S 24 +#define AM_REG_GPIO_ALTPADCFGI_PAD35_DS1_M 0x01000000 +#define AM_REG_GPIO_ALTPADCFGI_PAD35_DS1(n) (((uint32_t)(n) << 24) & 0x01000000) + +// Pad 34 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGI_PAD34_SR_S 20 +#define AM_REG_GPIO_ALTPADCFGI_PAD34_SR_M 0x00100000 +#define AM_REG_GPIO_ALTPADCFGI_PAD34_SR(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_GPIO_ALTPADCFGI_PAD34_SR_SR_EN 0x00100000 + +// Pad 34 high order drive strength selection. Used in conjunction with +// PAD34STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGI_PAD34_DS1_S 16 +#define AM_REG_GPIO_ALTPADCFGI_PAD34_DS1_M 0x00010000 +#define AM_REG_GPIO_ALTPADCFGI_PAD34_DS1(n) (((uint32_t)(n) << 16) & 0x00010000) + +// Pad 33 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGI_PAD33_SR_S 12 +#define AM_REG_GPIO_ALTPADCFGI_PAD33_SR_M 0x00001000 +#define AM_REG_GPIO_ALTPADCFGI_PAD33_SR(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_ALTPADCFGI_PAD33_SR_SR_EN 0x00001000 + +// Pad 33 high order drive strength selection. Used in conjunction with +// PAD33STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGI_PAD33_DS1_S 8 +#define AM_REG_GPIO_ALTPADCFGI_PAD33_DS1_M 0x00000100 +#define AM_REG_GPIO_ALTPADCFGI_PAD33_DS1(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Pad 32 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGI_PAD32_SR_S 4 +#define AM_REG_GPIO_ALTPADCFGI_PAD32_SR_M 0x00000010 +#define AM_REG_GPIO_ALTPADCFGI_PAD32_SR(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_ALTPADCFGI_PAD32_SR_SR_EN 0x00000010 + +// Pad 32 high order drive strength selection. Used in conjunction with +// PAD32STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGI_PAD32_DS1_S 0 +#define AM_REG_GPIO_ALTPADCFGI_PAD32_DS1_M 0x00000001 +#define AM_REG_GPIO_ALTPADCFGI_PAD32_DS1(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_ALTPADCFGJ - Alternate Pad Configuration reg9 (Pads 39,38,37,36) +// +//***************************************************************************** +// Pad 39 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGJ_PAD39_SR_S 28 +#define AM_REG_GPIO_ALTPADCFGJ_PAD39_SR_M 0x10000000 +#define AM_REG_GPIO_ALTPADCFGJ_PAD39_SR(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_GPIO_ALTPADCFGJ_PAD39_SR_SR_EN 0x10000000 + +// Pad 39 high order drive strength selection. Used in conjunction with +// PAD39STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGJ_PAD39_DS1_S 24 +#define AM_REG_GPIO_ALTPADCFGJ_PAD39_DS1_M 0x01000000 +#define AM_REG_GPIO_ALTPADCFGJ_PAD39_DS1(n) (((uint32_t)(n) << 24) & 0x01000000) + +// Pad 38 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGJ_PAD38_SR_S 20 +#define AM_REG_GPIO_ALTPADCFGJ_PAD38_SR_M 0x00100000 +#define AM_REG_GPIO_ALTPADCFGJ_PAD38_SR(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_GPIO_ALTPADCFGJ_PAD38_SR_SR_EN 0x00100000 + +// Pad 38 high order drive strength selection. Used in conjunction with +// PAD38STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGJ_PAD38_DS1_S 16 +#define AM_REG_GPIO_ALTPADCFGJ_PAD38_DS1_M 0x00010000 +#define AM_REG_GPIO_ALTPADCFGJ_PAD38_DS1(n) (((uint32_t)(n) << 16) & 0x00010000) + +// Pad 37 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGJ_PAD37_SR_S 12 +#define AM_REG_GPIO_ALTPADCFGJ_PAD37_SR_M 0x00001000 +#define AM_REG_GPIO_ALTPADCFGJ_PAD37_SR(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_ALTPADCFGJ_PAD37_SR_SR_EN 0x00001000 + +// Pad 37 high order drive strength selection. Used in conjunction with +// PAD37STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGJ_PAD37_DS1_S 8 +#define AM_REG_GPIO_ALTPADCFGJ_PAD37_DS1_M 0x00000100 +#define AM_REG_GPIO_ALTPADCFGJ_PAD37_DS1(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Pad 36 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGJ_PAD36_SR_S 4 +#define AM_REG_GPIO_ALTPADCFGJ_PAD36_SR_M 0x00000010 +#define AM_REG_GPIO_ALTPADCFGJ_PAD36_SR(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_ALTPADCFGJ_PAD36_SR_SR_EN 0x00000010 + +// Pad 36 high order drive strength selection. Used in conjunction with +// PAD36STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGJ_PAD36_DS1_S 0 +#define AM_REG_GPIO_ALTPADCFGJ_PAD36_DS1_M 0x00000001 +#define AM_REG_GPIO_ALTPADCFGJ_PAD36_DS1(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_ALTPADCFGK - Alternate Pad Configuration reg10 (Pads 43,42,41,40) +// +//***************************************************************************** +// Pad 43 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGK_PAD43_SR_S 28 +#define AM_REG_GPIO_ALTPADCFGK_PAD43_SR_M 0x10000000 +#define AM_REG_GPIO_ALTPADCFGK_PAD43_SR(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_GPIO_ALTPADCFGK_PAD43_SR_SR_EN 0x10000000 + +// Pad 43 high order drive strength selection. Used in conjunction with +// PAD43STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGK_PAD43_DS1_S 24 +#define AM_REG_GPIO_ALTPADCFGK_PAD43_DS1_M 0x01000000 +#define AM_REG_GPIO_ALTPADCFGK_PAD43_DS1(n) (((uint32_t)(n) << 24) & 0x01000000) + +// Pad 42 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGK_PAD42_SR_S 20 +#define AM_REG_GPIO_ALTPADCFGK_PAD42_SR_M 0x00100000 +#define AM_REG_GPIO_ALTPADCFGK_PAD42_SR(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_GPIO_ALTPADCFGK_PAD42_SR_SR_EN 0x00100000 + +// Pad 42 high order drive strength selection. Used in conjunction with +// PAD42STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGK_PAD42_DS1_S 16 +#define AM_REG_GPIO_ALTPADCFGK_PAD42_DS1_M 0x00010000 +#define AM_REG_GPIO_ALTPADCFGK_PAD42_DS1(n) (((uint32_t)(n) << 16) & 0x00010000) + +// Pad 41 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGK_PAD41_SR_S 12 +#define AM_REG_GPIO_ALTPADCFGK_PAD41_SR_M 0x00001000 +#define AM_REG_GPIO_ALTPADCFGK_PAD41_SR(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_ALTPADCFGK_PAD41_SR_SR_EN 0x00001000 + +// Pad 41 high order drive strength selection. Used in conjunction with +// PAD41STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGK_PAD41_DS1_S 8 +#define AM_REG_GPIO_ALTPADCFGK_PAD41_DS1_M 0x00000100 +#define AM_REG_GPIO_ALTPADCFGK_PAD41_DS1(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Pad 40 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGK_PAD40_SR_S 4 +#define AM_REG_GPIO_ALTPADCFGK_PAD40_SR_M 0x00000010 +#define AM_REG_GPIO_ALTPADCFGK_PAD40_SR(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_ALTPADCFGK_PAD40_SR_SR_EN 0x00000010 + +// Pad 40 high order drive strength selection. Used in conjunction with +// PAD40STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGK_PAD40_DS1_S 0 +#define AM_REG_GPIO_ALTPADCFGK_PAD40_DS1_M 0x00000001 +#define AM_REG_GPIO_ALTPADCFGK_PAD40_DS1(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_ALTPADCFGL - Alternate Pad Configuration reg11 (Pads 47,46,45,44) +// +//***************************************************************************** +// Pad 47 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGL_PAD47_SR_S 28 +#define AM_REG_GPIO_ALTPADCFGL_PAD47_SR_M 0x10000000 +#define AM_REG_GPIO_ALTPADCFGL_PAD47_SR(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_GPIO_ALTPADCFGL_PAD47_SR_SR_EN 0x10000000 + +// Pad 47 high order drive strength selection. Used in conjunction with +// PAD47STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGL_PAD47_DS1_S 24 +#define AM_REG_GPIO_ALTPADCFGL_PAD47_DS1_M 0x01000000 +#define AM_REG_GPIO_ALTPADCFGL_PAD47_DS1(n) (((uint32_t)(n) << 24) & 0x01000000) + +// Pad 46 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGL_PAD46_SR_S 20 +#define AM_REG_GPIO_ALTPADCFGL_PAD46_SR_M 0x00100000 +#define AM_REG_GPIO_ALTPADCFGL_PAD46_SR(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_GPIO_ALTPADCFGL_PAD46_SR_SR_EN 0x00100000 + +// Pad 46 high order drive strength selection. Used in conjunction with +// PAD46STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGL_PAD46_DS1_S 16 +#define AM_REG_GPIO_ALTPADCFGL_PAD46_DS1_M 0x00010000 +#define AM_REG_GPIO_ALTPADCFGL_PAD46_DS1(n) (((uint32_t)(n) << 16) & 0x00010000) + +// Pad 45 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGL_PAD45_SR_S 12 +#define AM_REG_GPIO_ALTPADCFGL_PAD45_SR_M 0x00001000 +#define AM_REG_GPIO_ALTPADCFGL_PAD45_SR(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_ALTPADCFGL_PAD45_SR_SR_EN 0x00001000 + +// Pad 45 high order drive strength selection. Used in conjunction with +// PAD45STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGL_PAD45_DS1_S 8 +#define AM_REG_GPIO_ALTPADCFGL_PAD45_DS1_M 0x00000100 +#define AM_REG_GPIO_ALTPADCFGL_PAD45_DS1(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Pad 44 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGL_PAD44_SR_S 4 +#define AM_REG_GPIO_ALTPADCFGL_PAD44_SR_M 0x00000010 +#define AM_REG_GPIO_ALTPADCFGL_PAD44_SR(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_ALTPADCFGL_PAD44_SR_SR_EN 0x00000010 + +// Pad 44 high order drive strength selection. Used in conjunction with +// PAD44STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGL_PAD44_DS1_S 0 +#define AM_REG_GPIO_ALTPADCFGL_PAD44_DS1_M 0x00000001 +#define AM_REG_GPIO_ALTPADCFGL_PAD44_DS1(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// GPIO_ALTPADCFGM - Alternate Pad Configuration reg12 (Pads 49,48) +// +//***************************************************************************** +// Pad 49 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGM_PAD49_SR_S 12 +#define AM_REG_GPIO_ALTPADCFGM_PAD49_SR_M 0x00001000 +#define AM_REG_GPIO_ALTPADCFGM_PAD49_SR(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_GPIO_ALTPADCFGM_PAD49_SR_SR_EN 0x00001000 + +// Pad 49 high order drive strength selection. Used in conjunction with +// PAD49STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGM_PAD49_DS1_S 8 +#define AM_REG_GPIO_ALTPADCFGM_PAD49_DS1_M 0x00000100 +#define AM_REG_GPIO_ALTPADCFGM_PAD49_DS1(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Pad 48 slew rate selection. +#define AM_REG_GPIO_ALTPADCFGM_PAD48_SR_S 4 +#define AM_REG_GPIO_ALTPADCFGM_PAD48_SR_M 0x00000010 +#define AM_REG_GPIO_ALTPADCFGM_PAD48_SR(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_GPIO_ALTPADCFGM_PAD48_SR_SR_EN 0x00000010 + +// Pad 48 high order drive strength selection. Used in conjunction with +// PAD48STRNG field to set the pad drive strength. +#define AM_REG_GPIO_ALTPADCFGM_PAD48_DS1_S 0 +#define AM_REG_GPIO_ALTPADCFGM_PAD48_DS1_M 0x00000001 +#define AM_REG_GPIO_ALTPADCFGM_PAD48_DS1(n) (((uint32_t)(n) << 0) & 0x00000001) + +#endif // AM_REG_GPIO_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_iomstr.h b/bsp/apollo2/libraries/drivers/regs/am_reg_iomstr.h new file mode 100644 index 0000000000..c04cd2c04a --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_iomstr.h @@ -0,0 +1,587 @@ +//***************************************************************************** +// +// am_reg_iomstr.h +//! @file +//! +//! @brief Register macros for the IOMSTR module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_IOMSTR_H +#define AM_REG_IOMSTR_H + +//***************************************************************************** +// +// Instance finder. (6 instance(s) available) +// +//***************************************************************************** +#define AM_REG_IOMSTR_NUM_MODULES 6 +#define AM_REG_IOMSTRn(n) \ + (REG_IOMSTR_BASEADDR + 0x00001000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_IOMSTR_FIFO_O 0x00000000 +#define AM_REG_IOMSTR_FIFOPTR_O 0x00000100 +#define AM_REG_IOMSTR_TLNGTH_O 0x00000104 +#define AM_REG_IOMSTR_FIFOTHR_O 0x00000108 +#define AM_REG_IOMSTR_CLKCFG_O 0x0000010C +#define AM_REG_IOMSTR_CMD_O 0x00000110 +#define AM_REG_IOMSTR_CMDRPT_O 0x00000114 +#define AM_REG_IOMSTR_STATUS_O 0x00000118 +#define AM_REG_IOMSTR_CFG_O 0x0000011C +#define AM_REG_IOMSTR_INTEN_O 0x00000200 +#define AM_REG_IOMSTR_INTSTAT_O 0x00000204 +#define AM_REG_IOMSTR_INTCLR_O 0x00000208 +#define AM_REG_IOMSTR_INTSET_O 0x0000020C + +//***************************************************************************** +// +// IOMSTR_INTEN - IO Master Interrupts: Enable +// +//***************************************************************************** +// This is the arbitration loss interrupt. This error occurs if another master +// collides with an IO Master transfer. Generally, the IOM started an operation +// but found SDA already low. +#define AM_REG_IOMSTR_INTEN_ARB_S 10 +#define AM_REG_IOMSTR_INTEN_ARB_M 0x00000400 +#define AM_REG_IOMSTR_INTEN_ARB(n) (((uint32_t)(n) << 10) & 0x00000400) + +// This is the STOP command interrupt. A STOP bit was detected by the IOM. +#define AM_REG_IOMSTR_INTEN_STOP_S 9 +#define AM_REG_IOMSTR_INTEN_STOP_M 0x00000200 +#define AM_REG_IOMSTR_INTEN_STOP(n) (((uint32_t)(n) << 9) & 0x00000200) + +// This is the START command interrupt. A START from another master was +// detected. Software must wait for a STOP before proceeding. +#define AM_REG_IOMSTR_INTEN_START_S 8 +#define AM_REG_IOMSTR_INTEN_START_M 0x00000100 +#define AM_REG_IOMSTR_INTEN_START(n) (((uint32_t)(n) << 8) & 0x00000100) + +// This is the illegal command interrupt. Software attempted to issue a CMD +// while another CMD was already in progress. Or an attempt was made to issue a +// non-zero-length write CMD with an empty FIFO. +#define AM_REG_IOMSTR_INTEN_ICMD_S 7 +#define AM_REG_IOMSTR_INTEN_ICMD_M 0x00000080 +#define AM_REG_IOMSTR_INTEN_ICMD(n) (((uint32_t)(n) << 7) & 0x00000080) + +// This is the illegal FIFO access interrupt. An attempt was made to read the +// FIFO during a write CMD. Or an attempt was made to write the FIFO on a read +// CMD. +#define AM_REG_IOMSTR_INTEN_IACC_S 6 +#define AM_REG_IOMSTR_INTEN_IACC_M 0x00000040 +#define AM_REG_IOMSTR_INTEN_IACC(n) (((uint32_t)(n) << 6) & 0x00000040) + +// This is the WTLEN interrupt. +#define AM_REG_IOMSTR_INTEN_WTLEN_S 5 +#define AM_REG_IOMSTR_INTEN_WTLEN_M 0x00000020 +#define AM_REG_IOMSTR_INTEN_WTLEN(n) (((uint32_t)(n) << 5) & 0x00000020) + +// This is the I2C NAK interrupt. The expected ACK from the slave was not +// received by the IOM. +#define AM_REG_IOMSTR_INTEN_NAK_S 4 +#define AM_REG_IOMSTR_INTEN_NAK_M 0x00000010 +#define AM_REG_IOMSTR_INTEN_NAK(n) (((uint32_t)(n) << 4) & 0x00000010) + +// This is the Write FIFO Overflow interrupt. An attempt was made to write the +// FIFO while it was full (i.e. while FIFOSIZ > 124). +#define AM_REG_IOMSTR_INTEN_FOVFL_S 3 +#define AM_REG_IOMSTR_INTEN_FOVFL_M 0x00000008 +#define AM_REG_IOMSTR_INTEN_FOVFL(n) (((uint32_t)(n) << 3) & 0x00000008) + +// This is the Read FIFO Underflow interrupt. An attempt was made to read FIFO +// when empty (i.e. while FIFOSIZ less than 4). +#define AM_REG_IOMSTR_INTEN_FUNDFL_S 2 +#define AM_REG_IOMSTR_INTEN_FUNDFL_M 0x00000004 +#define AM_REG_IOMSTR_INTEN_FUNDFL(n) (((uint32_t)(n) << 2) & 0x00000004) + +// This is the FIFO Threshold interrupt. +#define AM_REG_IOMSTR_INTEN_THR_S 1 +#define AM_REG_IOMSTR_INTEN_THR_M 0x00000002 +#define AM_REG_IOMSTR_INTEN_THR(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This is the Command Complete interrupt. +#define AM_REG_IOMSTR_INTEN_CMDCMP_S 0 +#define AM_REG_IOMSTR_INTEN_CMDCMP_M 0x00000001 +#define AM_REG_IOMSTR_INTEN_CMDCMP(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// IOMSTR_INTSTAT - IO Master Interrupts: Status +// +//***************************************************************************** +// This is the arbitration loss interrupt. This error occurs if another master +// collides with an IO Master transfer. Generally, the IOM started an operation +// but found SDA already low. +#define AM_REG_IOMSTR_INTSTAT_ARB_S 10 +#define AM_REG_IOMSTR_INTSTAT_ARB_M 0x00000400 +#define AM_REG_IOMSTR_INTSTAT_ARB(n) (((uint32_t)(n) << 10) & 0x00000400) + +// This is the STOP command interrupt. A STOP bit was detected by the IOM. +#define AM_REG_IOMSTR_INTSTAT_STOP_S 9 +#define AM_REG_IOMSTR_INTSTAT_STOP_M 0x00000200 +#define AM_REG_IOMSTR_INTSTAT_STOP(n) (((uint32_t)(n) << 9) & 0x00000200) + +// This is the START command interrupt. A START from another master was +// detected. Software must wait for a STOP before proceeding. +#define AM_REG_IOMSTR_INTSTAT_START_S 8 +#define AM_REG_IOMSTR_INTSTAT_START_M 0x00000100 +#define AM_REG_IOMSTR_INTSTAT_START(n) (((uint32_t)(n) << 8) & 0x00000100) + +// This is the illegal command interrupt. Software attempted to issue a CMD +// while another CMD was already in progress. Or an attempt was made to issue a +// non-zero-length write CMD with an empty FIFO. +#define AM_REG_IOMSTR_INTSTAT_ICMD_S 7 +#define AM_REG_IOMSTR_INTSTAT_ICMD_M 0x00000080 +#define AM_REG_IOMSTR_INTSTAT_ICMD(n) (((uint32_t)(n) << 7) & 0x00000080) + +// This is the illegal FIFO access interrupt. An attempt was made to read the +// FIFO during a write CMD. Or an attempt was made to write the FIFO on a read +// CMD. +#define AM_REG_IOMSTR_INTSTAT_IACC_S 6 +#define AM_REG_IOMSTR_INTSTAT_IACC_M 0x00000040 +#define AM_REG_IOMSTR_INTSTAT_IACC(n) (((uint32_t)(n) << 6) & 0x00000040) + +// This is the WTLEN interrupt. +#define AM_REG_IOMSTR_INTSTAT_WTLEN_S 5 +#define AM_REG_IOMSTR_INTSTAT_WTLEN_M 0x00000020 +#define AM_REG_IOMSTR_INTSTAT_WTLEN(n) (((uint32_t)(n) << 5) & 0x00000020) + +// This is the I2C NAK interrupt. The expected ACK from the slave was not +// received by the IOM. +#define AM_REG_IOMSTR_INTSTAT_NAK_S 4 +#define AM_REG_IOMSTR_INTSTAT_NAK_M 0x00000010 +#define AM_REG_IOMSTR_INTSTAT_NAK(n) (((uint32_t)(n) << 4) & 0x00000010) + +// This is the Write FIFO Overflow interrupt. An attempt was made to write the +// FIFO while it was full (i.e. while FIFOSIZ > 124). +#define AM_REG_IOMSTR_INTSTAT_FOVFL_S 3 +#define AM_REG_IOMSTR_INTSTAT_FOVFL_M 0x00000008 +#define AM_REG_IOMSTR_INTSTAT_FOVFL(n) (((uint32_t)(n) << 3) & 0x00000008) + +// This is the Read FIFO Underflow interrupt. An attempt was made to read FIFO +// when empty (i.e. while FIFOSIZ less than 4). +#define AM_REG_IOMSTR_INTSTAT_FUNDFL_S 2 +#define AM_REG_IOMSTR_INTSTAT_FUNDFL_M 0x00000004 +#define AM_REG_IOMSTR_INTSTAT_FUNDFL(n) (((uint32_t)(n) << 2) & 0x00000004) + +// This is the FIFO Threshold interrupt. +#define AM_REG_IOMSTR_INTSTAT_THR_S 1 +#define AM_REG_IOMSTR_INTSTAT_THR_M 0x00000002 +#define AM_REG_IOMSTR_INTSTAT_THR(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This is the Command Complete interrupt. +#define AM_REG_IOMSTR_INTSTAT_CMDCMP_S 0 +#define AM_REG_IOMSTR_INTSTAT_CMDCMP_M 0x00000001 +#define AM_REG_IOMSTR_INTSTAT_CMDCMP(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// IOMSTR_INTCLR - IO Master Interrupts: Clear +// +//***************************************************************************** +// This is the arbitration loss interrupt. This error occurs if another master +// collides with an IO Master transfer. Generally, the IOM started an operation +// but found SDA already low. +#define AM_REG_IOMSTR_INTCLR_ARB_S 10 +#define AM_REG_IOMSTR_INTCLR_ARB_M 0x00000400 +#define AM_REG_IOMSTR_INTCLR_ARB(n) (((uint32_t)(n) << 10) & 0x00000400) + +// This is the STOP command interrupt. A STOP bit was detected by the IOM. +#define AM_REG_IOMSTR_INTCLR_STOP_S 9 +#define AM_REG_IOMSTR_INTCLR_STOP_M 0x00000200 +#define AM_REG_IOMSTR_INTCLR_STOP(n) (((uint32_t)(n) << 9) & 0x00000200) + +// This is the START command interrupt. A START from another master was +// detected. Software must wait for a STOP before proceeding. +#define AM_REG_IOMSTR_INTCLR_START_S 8 +#define AM_REG_IOMSTR_INTCLR_START_M 0x00000100 +#define AM_REG_IOMSTR_INTCLR_START(n) (((uint32_t)(n) << 8) & 0x00000100) + +// This is the illegal command interrupt. Software attempted to issue a CMD +// while another CMD was already in progress. Or an attempt was made to issue a +// non-zero-length write CMD with an empty FIFO. +#define AM_REG_IOMSTR_INTCLR_ICMD_S 7 +#define AM_REG_IOMSTR_INTCLR_ICMD_M 0x00000080 +#define AM_REG_IOMSTR_INTCLR_ICMD(n) (((uint32_t)(n) << 7) & 0x00000080) + +// This is the illegal FIFO access interrupt. An attempt was made to read the +// FIFO during a write CMD. Or an attempt was made to write the FIFO on a read +// CMD. +#define AM_REG_IOMSTR_INTCLR_IACC_S 6 +#define AM_REG_IOMSTR_INTCLR_IACC_M 0x00000040 +#define AM_REG_IOMSTR_INTCLR_IACC(n) (((uint32_t)(n) << 6) & 0x00000040) + +// This is the WTLEN interrupt. +#define AM_REG_IOMSTR_INTCLR_WTLEN_S 5 +#define AM_REG_IOMSTR_INTCLR_WTLEN_M 0x00000020 +#define AM_REG_IOMSTR_INTCLR_WTLEN(n) (((uint32_t)(n) << 5) & 0x00000020) + +// This is the I2C NAK interrupt. The expected ACK from the slave was not +// received by the IOM. +#define AM_REG_IOMSTR_INTCLR_NAK_S 4 +#define AM_REG_IOMSTR_INTCLR_NAK_M 0x00000010 +#define AM_REG_IOMSTR_INTCLR_NAK(n) (((uint32_t)(n) << 4) & 0x00000010) + +// This is the Write FIFO Overflow interrupt. An attempt was made to write the +// FIFO while it was full (i.e. while FIFOSIZ > 124). +#define AM_REG_IOMSTR_INTCLR_FOVFL_S 3 +#define AM_REG_IOMSTR_INTCLR_FOVFL_M 0x00000008 +#define AM_REG_IOMSTR_INTCLR_FOVFL(n) (((uint32_t)(n) << 3) & 0x00000008) + +// This is the Read FIFO Underflow interrupt. An attempt was made to read FIFO +// when empty (i.e. while FIFOSIZ less than 4). +#define AM_REG_IOMSTR_INTCLR_FUNDFL_S 2 +#define AM_REG_IOMSTR_INTCLR_FUNDFL_M 0x00000004 +#define AM_REG_IOMSTR_INTCLR_FUNDFL(n) (((uint32_t)(n) << 2) & 0x00000004) + +// This is the FIFO Threshold interrupt. +#define AM_REG_IOMSTR_INTCLR_THR_S 1 +#define AM_REG_IOMSTR_INTCLR_THR_M 0x00000002 +#define AM_REG_IOMSTR_INTCLR_THR(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This is the Command Complete interrupt. +#define AM_REG_IOMSTR_INTCLR_CMDCMP_S 0 +#define AM_REG_IOMSTR_INTCLR_CMDCMP_M 0x00000001 +#define AM_REG_IOMSTR_INTCLR_CMDCMP(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// IOMSTR_INTSET - IO Master Interrupts: Set +// +//***************************************************************************** +// This is the arbitration loss interrupt. This error occurs if another master +// collides with an IO Master transfer. Generally, the IOM started an operation +// but found SDA already low. +#define AM_REG_IOMSTR_INTSET_ARB_S 10 +#define AM_REG_IOMSTR_INTSET_ARB_M 0x00000400 +#define AM_REG_IOMSTR_INTSET_ARB(n) (((uint32_t)(n) << 10) & 0x00000400) + +// This is the STOP command interrupt. A STOP bit was detected by the IOM. +#define AM_REG_IOMSTR_INTSET_STOP_S 9 +#define AM_REG_IOMSTR_INTSET_STOP_M 0x00000200 +#define AM_REG_IOMSTR_INTSET_STOP(n) (((uint32_t)(n) << 9) & 0x00000200) + +// This is the START command interrupt. A START from another master was +// detected. Software must wait for a STOP before proceeding. +#define AM_REG_IOMSTR_INTSET_START_S 8 +#define AM_REG_IOMSTR_INTSET_START_M 0x00000100 +#define AM_REG_IOMSTR_INTSET_START(n) (((uint32_t)(n) << 8) & 0x00000100) + +// This is the illegal command interrupt. Software attempted to issue a CMD +// while another CMD was already in progress. Or an attempt was made to issue a +// non-zero-length write CMD with an empty FIFO. +#define AM_REG_IOMSTR_INTSET_ICMD_S 7 +#define AM_REG_IOMSTR_INTSET_ICMD_M 0x00000080 +#define AM_REG_IOMSTR_INTSET_ICMD(n) (((uint32_t)(n) << 7) & 0x00000080) + +// This is the illegal FIFO access interrupt. An attempt was made to read the +// FIFO during a write CMD. Or an attempt was made to write the FIFO on a read +// CMD. +#define AM_REG_IOMSTR_INTSET_IACC_S 6 +#define AM_REG_IOMSTR_INTSET_IACC_M 0x00000040 +#define AM_REG_IOMSTR_INTSET_IACC(n) (((uint32_t)(n) << 6) & 0x00000040) + +// This is the WTLEN interrupt. +#define AM_REG_IOMSTR_INTSET_WTLEN_S 5 +#define AM_REG_IOMSTR_INTSET_WTLEN_M 0x00000020 +#define AM_REG_IOMSTR_INTSET_WTLEN(n) (((uint32_t)(n) << 5) & 0x00000020) + +// This is the I2C NAK interrupt. The expected ACK from the slave was not +// received by the IOM. +#define AM_REG_IOMSTR_INTSET_NAK_S 4 +#define AM_REG_IOMSTR_INTSET_NAK_M 0x00000010 +#define AM_REG_IOMSTR_INTSET_NAK(n) (((uint32_t)(n) << 4) & 0x00000010) + +// This is the Write FIFO Overflow interrupt. An attempt was made to write the +// FIFO while it was full (i.e. while FIFOSIZ > 124). +#define AM_REG_IOMSTR_INTSET_FOVFL_S 3 +#define AM_REG_IOMSTR_INTSET_FOVFL_M 0x00000008 +#define AM_REG_IOMSTR_INTSET_FOVFL(n) (((uint32_t)(n) << 3) & 0x00000008) + +// This is the Read FIFO Underflow interrupt. An attempt was made to read FIFO +// when empty (i.e. while FIFOSIZ less than 4). +#define AM_REG_IOMSTR_INTSET_FUNDFL_S 2 +#define AM_REG_IOMSTR_INTSET_FUNDFL_M 0x00000004 +#define AM_REG_IOMSTR_INTSET_FUNDFL(n) (((uint32_t)(n) << 2) & 0x00000004) + +// This is the FIFO Threshold interrupt. +#define AM_REG_IOMSTR_INTSET_THR_S 1 +#define AM_REG_IOMSTR_INTSET_THR_M 0x00000002 +#define AM_REG_IOMSTR_INTSET_THR(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This is the Command Complete interrupt. +#define AM_REG_IOMSTR_INTSET_CMDCMP_S 0 +#define AM_REG_IOMSTR_INTSET_CMDCMP_M 0x00000001 +#define AM_REG_IOMSTR_INTSET_CMDCMP(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// IOMSTR_FIFO - FIFO Access Port +// +//***************************************************************************** +// FIFO access port. +#define AM_REG_IOMSTR_FIFO_FIFO_S 0 +#define AM_REG_IOMSTR_FIFO_FIFO_M 0xFFFFFFFF +#define AM_REG_IOMSTR_FIFO_FIFO(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// IOMSTR_FIFOPTR - Current FIFO Pointers +// +//***************************************************************************** +// The number of bytes remaining in the FIFO (i.e. 128-FIFOSIZ if FULLDUP = 0 or +// 64-FIFOSIZ if FULLDUP = 1)). +#define AM_REG_IOMSTR_FIFOPTR_FIFOREM_S 16 +#define AM_REG_IOMSTR_FIFOPTR_FIFOREM_M 0x00FF0000 +#define AM_REG_IOMSTR_FIFOPTR_FIFOREM(n) (((uint32_t)(n) << 16) & 0x00FF0000) + +// The number of bytes currently in the FIFO. +#define AM_REG_IOMSTR_FIFOPTR_FIFOSIZ_S 0 +#define AM_REG_IOMSTR_FIFOPTR_FIFOSIZ_M 0x000000FF +#define AM_REG_IOMSTR_FIFOPTR_FIFOSIZ(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// IOMSTR_TLNGTH - Transfer Length +// +//***************************************************************************** +// Remaining transfer length. +#define AM_REG_IOMSTR_TLNGTH_TLNGTH_S 0 +#define AM_REG_IOMSTR_TLNGTH_TLNGTH_M 0x00000FFF +#define AM_REG_IOMSTR_TLNGTH_TLNGTH(n) (((uint32_t)(n) << 0) & 0x00000FFF) + +//***************************************************************************** +// +// IOMSTR_FIFOTHR - FIFO Threshold Configuration +// +//***************************************************************************** +// FIFO write threshold. +#define AM_REG_IOMSTR_FIFOTHR_FIFOWTHR_S 8 +#define AM_REG_IOMSTR_FIFOTHR_FIFOWTHR_M 0x00007F00 +#define AM_REG_IOMSTR_FIFOTHR_FIFOWTHR(n) (((uint32_t)(n) << 8) & 0x00007F00) + +// FIFO read threshold. +#define AM_REG_IOMSTR_FIFOTHR_FIFORTHR_S 0 +#define AM_REG_IOMSTR_FIFOTHR_FIFORTHR_M 0x0000007F +#define AM_REG_IOMSTR_FIFOTHR_FIFORTHR(n) (((uint32_t)(n) << 0) & 0x0000007F) + +//***************************************************************************** +// +// IOMSTR_CLKCFG - I/O Clock Configuration +// +//***************************************************************************** +// Clock total count minus 1. +#define AM_REG_IOMSTR_CLKCFG_TOTPER_S 24 +#define AM_REG_IOMSTR_CLKCFG_TOTPER_M 0xFF000000 +#define AM_REG_IOMSTR_CLKCFG_TOTPER(n) (((uint32_t)(n) << 24) & 0xFF000000) + +// Clock low count minus 1. +#define AM_REG_IOMSTR_CLKCFG_LOWPER_S 16 +#define AM_REG_IOMSTR_CLKCFG_LOWPER_M 0x00FF0000 +#define AM_REG_IOMSTR_CLKCFG_LOWPER(n) (((uint32_t)(n) << 16) & 0x00FF0000) + +// Enable clock division by TOTPER. +#define AM_REG_IOMSTR_CLKCFG_DIVEN_S 12 +#define AM_REG_IOMSTR_CLKCFG_DIVEN_M 0x00001000 +#define AM_REG_IOMSTR_CLKCFG_DIVEN(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_IOMSTR_CLKCFG_DIVEN_DIS 0x00000000 +#define AM_REG_IOMSTR_CLKCFG_DIVEN_EN 0x00001000 + +// Enable divide by 3. +#define AM_REG_IOMSTR_CLKCFG_DIV3_S 11 +#define AM_REG_IOMSTR_CLKCFG_DIV3_M 0x00000800 +#define AM_REG_IOMSTR_CLKCFG_DIV3(n) (((uint32_t)(n) << 11) & 0x00000800) +#define AM_REG_IOMSTR_CLKCFG_DIV3_DIS 0x00000000 +#define AM_REG_IOMSTR_CLKCFG_DIV3_EN 0x00000800 + +// Select the input clock frequency. +#define AM_REG_IOMSTR_CLKCFG_FSEL_S 8 +#define AM_REG_IOMSTR_CLKCFG_FSEL_M 0x00000700 +#define AM_REG_IOMSTR_CLKCFG_FSEL(n) (((uint32_t)(n) << 8) & 0x00000700) +#define AM_REG_IOMSTR_CLKCFG_FSEL_MIN_PWR 0x00000000 +#define AM_REG_IOMSTR_CLKCFG_FSEL_HFRC 0x00000100 +#define AM_REG_IOMSTR_CLKCFG_FSEL_HFRC_DIV2 0x00000200 +#define AM_REG_IOMSTR_CLKCFG_FSEL_HFRC_DIV4 0x00000300 +#define AM_REG_IOMSTR_CLKCFG_FSEL_HFRC_DIV8 0x00000400 +#define AM_REG_IOMSTR_CLKCFG_FSEL_HFRC_DIV16 0x00000500 +#define AM_REG_IOMSTR_CLKCFG_FSEL_HFRC_DIV32 0x00000600 +#define AM_REG_IOMSTR_CLKCFG_FSEL_HFRC_DIV64 0x00000700 + +//***************************************************************************** +// +// IOMSTR_CMD - Command Register +// +//***************************************************************************** +// This register holds the I/O Command +#define AM_REG_IOMSTR_CMD_CMD_S 0 +#define AM_REG_IOMSTR_CMD_CMD_M 0xFFFFFFFF +#define AM_REG_IOMSTR_CMD_CMD(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// IOMSTR_CMDRPT - Command Repeat Register +// +//***************************************************************************** +// These bits hold the Command repeat count. +#define AM_REG_IOMSTR_CMDRPT_CMDRPT_S 0 +#define AM_REG_IOMSTR_CMDRPT_CMDRPT_M 0x0000001F +#define AM_REG_IOMSTR_CMDRPT_CMDRPT(n) (((uint32_t)(n) << 0) & 0x0000001F) + +//***************************************************************************** +// +// IOMSTR_STATUS - Status Register +// +//***************************************************************************** +// This bit indicates if the I/O state machine is IDLE. +#define AM_REG_IOMSTR_STATUS_IDLEST_S 2 +#define AM_REG_IOMSTR_STATUS_IDLEST_M 0x00000004 +#define AM_REG_IOMSTR_STATUS_IDLEST(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_IOMSTR_STATUS_IDLEST_IDLE 0x00000004 + +// This bit indicates if the I/O Command is active. +#define AM_REG_IOMSTR_STATUS_CMDACT_S 1 +#define AM_REG_IOMSTR_STATUS_CMDACT_M 0x00000002 +#define AM_REG_IOMSTR_STATUS_CMDACT(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_IOMSTR_STATUS_CMDACT_ACTIVE 0x00000002 + +// This bit indicates if an error interrupt has occurred. +#define AM_REG_IOMSTR_STATUS_ERR_S 0 +#define AM_REG_IOMSTR_STATUS_ERR_M 0x00000001 +#define AM_REG_IOMSTR_STATUS_ERR(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_IOMSTR_STATUS_ERR_ERROR 0x00000001 + +//***************************************************************************** +// +// IOMSTR_CFG - I/O Master Configuration +// +//***************************************************************************** +// This bit enables the IO Master. +#define AM_REG_IOMSTR_CFG_IFCEN_S 31 +#define AM_REG_IOMSTR_CFG_IFCEN_M 0x80000000 +#define AM_REG_IOMSTR_CFG_IFCEN(n) (((uint32_t)(n) << 31) & 0x80000000) +#define AM_REG_IOMSTR_CFG_IFCEN_DIS 0x00000000 +#define AM_REG_IOMSTR_CFG_IFCEN_EN 0x80000000 + +// This bit selects the read flow control signal polarity. +#define AM_REG_IOMSTR_CFG_RDFCPOL_S 14 +#define AM_REG_IOMSTR_CFG_RDFCPOL_M 0x00004000 +#define AM_REG_IOMSTR_CFG_RDFCPOL(n) (((uint32_t)(n) << 14) & 0x00004000) +#define AM_REG_IOMSTR_CFG_RDFCPOL_HIGH 0x00000000 +#define AM_REG_IOMSTR_CFG_RDFCPOL_LOW 0x00004000 + +// This bit selects the write flow control signal polarity. +#define AM_REG_IOMSTR_CFG_WTFCPOL_S 13 +#define AM_REG_IOMSTR_CFG_WTFCPOL_M 0x00002000 +#define AM_REG_IOMSTR_CFG_WTFCPOL(n) (((uint32_t)(n) << 13) & 0x00002000) +#define AM_REG_IOMSTR_CFG_WTFCPOL_HIGH 0x00000000 +#define AM_REG_IOMSTR_CFG_WTFCPOL_LOW 0x00002000 + +// This bit selects the write mode flow control signal. +#define AM_REG_IOMSTR_CFG_WTFCIRQ_S 12 +#define AM_REG_IOMSTR_CFG_WTFCIRQ_M 0x00001000 +#define AM_REG_IOMSTR_CFG_WTFCIRQ(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_IOMSTR_CFG_WTFCIRQ_MISO 0x00000000 +#define AM_REG_IOMSTR_CFG_WTFCIRQ_IRQ 0x00001000 + +// This bit must be left at the default value of 0. +#define AM_REG_IOMSTR_CFG_FCDEL_S 11 +#define AM_REG_IOMSTR_CFG_FCDEL_M 0x00000800 +#define AM_REG_IOMSTR_CFG_FCDEL(n) (((uint32_t)(n) << 11) & 0x00000800) + +// This bit invewrts MOSI when flow control is enabled. +#define AM_REG_IOMSTR_CFG_MOSIINV_S 10 +#define AM_REG_IOMSTR_CFG_MOSIINV_M 0x00000400 +#define AM_REG_IOMSTR_CFG_MOSIINV(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_IOMSTR_CFG_MOSIINV_NORMAL 0x00000000 +#define AM_REG_IOMSTR_CFG_MOSIINV_INVERT 0x00000400 + +// This bit enables read mode flow control. +#define AM_REG_IOMSTR_CFG_RDFC_S 9 +#define AM_REG_IOMSTR_CFG_RDFC_M 0x00000200 +#define AM_REG_IOMSTR_CFG_RDFC(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_IOMSTR_CFG_RDFC_DIS 0x00000000 +#define AM_REG_IOMSTR_CFG_RDFC_EN 0x00000200 + +// This bit enables write mode flow control. +#define AM_REG_IOMSTR_CFG_WTFC_S 8 +#define AM_REG_IOMSTR_CFG_WTFC_M 0x00000100 +#define AM_REG_IOMSTR_CFG_WTFC(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_IOMSTR_CFG_WTFC_DIS 0x00000000 +#define AM_REG_IOMSTR_CFG_WTFC_EN 0x00000100 + +// This bit selects the preread timing. +#define AM_REG_IOMSTR_CFG_STARTRD_S 4 +#define AM_REG_IOMSTR_CFG_STARTRD_M 0x00000030 +#define AM_REG_IOMSTR_CFG_STARTRD(n) (((uint32_t)(n) << 4) & 0x00000030) +#define AM_REG_IOMSTR_CFG_STARTRD_PRERD0 0x00000000 +#define AM_REG_IOMSTR_CFG_STARTRD_PRERD1 0x00000010 +#define AM_REG_IOMSTR_CFG_STARTRD_PRERD2 0x00000020 +#define AM_REG_IOMSTR_CFG_STARTRD_PRERD3 0x00000030 + +// This bit selects full duplex mode. +#define AM_REG_IOMSTR_CFG_FULLDUP_S 3 +#define AM_REG_IOMSTR_CFG_FULLDUP_M 0x00000008 +#define AM_REG_IOMSTR_CFG_FULLDUP(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_IOMSTR_CFG_FULLDUP_NORMAL 0x00000000 +#define AM_REG_IOMSTR_CFG_FULLDUP_FULLDUP 0x00000008 + +// This bit selects SPI phase. +#define AM_REG_IOMSTR_CFG_SPHA_S 2 +#define AM_REG_IOMSTR_CFG_SPHA_M 0x00000004 +#define AM_REG_IOMSTR_CFG_SPHA(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_IOMSTR_CFG_SPHA_SAMPLE_LEADING_EDGE 0x00000000 +#define AM_REG_IOMSTR_CFG_SPHA_SAMPLE_TRAILING_EDGE 0x00000004 + +// This bit selects SPI polarity. +#define AM_REG_IOMSTR_CFG_SPOL_S 1 +#define AM_REG_IOMSTR_CFG_SPOL_M 0x00000002 +#define AM_REG_IOMSTR_CFG_SPOL(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_IOMSTR_CFG_SPOL_CLK_BASE_0 0x00000000 +#define AM_REG_IOMSTR_CFG_SPOL_CLK_BASE_1 0x00000002 + +// This bit selects the I/O interface. +#define AM_REG_IOMSTR_CFG_IFCSEL_S 0 +#define AM_REG_IOMSTR_CFG_IFCSEL_M 0x00000001 +#define AM_REG_IOMSTR_CFG_IFCSEL(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_IOMSTR_CFG_IFCSEL_I2C 0x00000000 +#define AM_REG_IOMSTR_CFG_IFCSEL_SPI 0x00000001 + +#endif // AM_REG_IOMSTR_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_ioslave.h b/bsp/apollo2/libraries/drivers/regs/am_reg_ioslave.h new file mode 100644 index 0000000000..4a1c96ae3c --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_ioslave.h @@ -0,0 +1,514 @@ +//***************************************************************************** +// +// am_reg_ioslave.h +//! @file +//! +//! @brief Register macros for the IOSLAVE module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_IOSLAVE_H +#define AM_REG_IOSLAVE_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_IOSLAVE_NUM_MODULES 1 +#define AM_REG_IOSLAVEn(n) \ + (REG_IOSLAVE_BASEADDR + 0x00000000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_IOSLAVE_FIFOPTR_O 0x00000100 +#define AM_REG_IOSLAVE_FIFOCFG_O 0x00000104 +#define AM_REG_IOSLAVE_FIFOTHR_O 0x00000108 +#define AM_REG_IOSLAVE_FUPD_O 0x0000010C +#define AM_REG_IOSLAVE_FIFOCTR_O 0x00000110 +#define AM_REG_IOSLAVE_FIFOINC_O 0x00000114 +#define AM_REG_IOSLAVE_CFG_O 0x00000118 +#define AM_REG_IOSLAVE_PRENC_O 0x0000011C +#define AM_REG_IOSLAVE_IOINTCTL_O 0x00000120 +#define AM_REG_IOSLAVE_GENADD_O 0x00000124 +#define AM_REG_IOSLAVE_INTEN_O 0x00000200 +#define AM_REG_IOSLAVE_INTSTAT_O 0x00000204 +#define AM_REG_IOSLAVE_INTCLR_O 0x00000208 +#define AM_REG_IOSLAVE_INTSET_O 0x0000020C +#define AM_REG_IOSLAVE_REGACCINTEN_O 0x00000210 +#define AM_REG_IOSLAVE_REGACCINTSTAT_O 0x00000214 +#define AM_REG_IOSLAVE_REGACCINTCLR_O 0x00000218 +#define AM_REG_IOSLAVE_REGACCINTSET_O 0x0000021C + +//***************************************************************************** +// +// IOSLAVE_INTEN - IO Slave Interrupts: Enable +// +//***************************************************************************** +// Transfer complete interrupt, write to register space. +#define AM_REG_IOSLAVE_INTEN_XCMPWR_S 9 +#define AM_REG_IOSLAVE_INTEN_XCMPWR_M 0x00000200 +#define AM_REG_IOSLAVE_INTEN_XCMPWR(n) (((uint32_t)(n) << 9) & 0x00000200) + +// Transfer complete interrupt, write to FIFO space. +#define AM_REG_IOSLAVE_INTEN_XCMPWF_S 8 +#define AM_REG_IOSLAVE_INTEN_XCMPWF_M 0x00000100 +#define AM_REG_IOSLAVE_INTEN_XCMPWF(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Transfer complete interrupt, read from register space. +#define AM_REG_IOSLAVE_INTEN_XCMPRR_S 7 +#define AM_REG_IOSLAVE_INTEN_XCMPRR_M 0x00000080 +#define AM_REG_IOSLAVE_INTEN_XCMPRR(n) (((uint32_t)(n) << 7) & 0x00000080) + +// Transfer complete interrupt, read from FIFO space. +#define AM_REG_IOSLAVE_INTEN_XCMPRF_S 6 +#define AM_REG_IOSLAVE_INTEN_XCMPRF_M 0x00000040 +#define AM_REG_IOSLAVE_INTEN_XCMPRF(n) (((uint32_t)(n) << 6) & 0x00000040) + +// I2C Interrupt Write interrupt. +#define AM_REG_IOSLAVE_INTEN_IOINTW_S 5 +#define AM_REG_IOSLAVE_INTEN_IOINTW_M 0x00000020 +#define AM_REG_IOSLAVE_INTEN_IOINTW(n) (((uint32_t)(n) << 5) & 0x00000020) + +// I2C General Address interrupt. +#define AM_REG_IOSLAVE_INTEN_GENAD_S 4 +#define AM_REG_IOSLAVE_INTEN_GENAD_M 0x00000010 +#define AM_REG_IOSLAVE_INTEN_GENAD(n) (((uint32_t)(n) << 4) & 0x00000010) + +// FIFO Read Error interrupt. +#define AM_REG_IOSLAVE_INTEN_FRDERR_S 3 +#define AM_REG_IOSLAVE_INTEN_FRDERR_M 0x00000008 +#define AM_REG_IOSLAVE_INTEN_FRDERR(n) (((uint32_t)(n) << 3) & 0x00000008) + +// FIFO Underflow interrupt. +#define AM_REG_IOSLAVE_INTEN_FUNDFL_S 2 +#define AM_REG_IOSLAVE_INTEN_FUNDFL_M 0x00000004 +#define AM_REG_IOSLAVE_INTEN_FUNDFL(n) (((uint32_t)(n) << 2) & 0x00000004) + +// FIFO Overflow interrupt. +#define AM_REG_IOSLAVE_INTEN_FOVFL_S 1 +#define AM_REG_IOSLAVE_INTEN_FOVFL_M 0x00000002 +#define AM_REG_IOSLAVE_INTEN_FOVFL(n) (((uint32_t)(n) << 1) & 0x00000002) + +// FIFO Size interrupt. +#define AM_REG_IOSLAVE_INTEN_FSIZE_S 0 +#define AM_REG_IOSLAVE_INTEN_FSIZE_M 0x00000001 +#define AM_REG_IOSLAVE_INTEN_FSIZE(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// IOSLAVE_INTSTAT - IO Slave Interrupts: Status +// +//***************************************************************************** +// Transfer complete interrupt, write to register space. +#define AM_REG_IOSLAVE_INTSTAT_XCMPWR_S 9 +#define AM_REG_IOSLAVE_INTSTAT_XCMPWR_M 0x00000200 +#define AM_REG_IOSLAVE_INTSTAT_XCMPWR(n) (((uint32_t)(n) << 9) & 0x00000200) + +// Transfer complete interrupt, write to FIFO space. +#define AM_REG_IOSLAVE_INTSTAT_XCMPWF_S 8 +#define AM_REG_IOSLAVE_INTSTAT_XCMPWF_M 0x00000100 +#define AM_REG_IOSLAVE_INTSTAT_XCMPWF(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Transfer complete interrupt, read from register space. +#define AM_REG_IOSLAVE_INTSTAT_XCMPRR_S 7 +#define AM_REG_IOSLAVE_INTSTAT_XCMPRR_M 0x00000080 +#define AM_REG_IOSLAVE_INTSTAT_XCMPRR(n) (((uint32_t)(n) << 7) & 0x00000080) + +// Transfer complete interrupt, read from FIFO space. +#define AM_REG_IOSLAVE_INTSTAT_XCMPRF_S 6 +#define AM_REG_IOSLAVE_INTSTAT_XCMPRF_M 0x00000040 +#define AM_REG_IOSLAVE_INTSTAT_XCMPRF(n) (((uint32_t)(n) << 6) & 0x00000040) + +// I2C Interrupt Write interrupt. +#define AM_REG_IOSLAVE_INTSTAT_IOINTW_S 5 +#define AM_REG_IOSLAVE_INTSTAT_IOINTW_M 0x00000020 +#define AM_REG_IOSLAVE_INTSTAT_IOINTW(n) (((uint32_t)(n) << 5) & 0x00000020) + +// I2C General Address interrupt. +#define AM_REG_IOSLAVE_INTSTAT_GENAD_S 4 +#define AM_REG_IOSLAVE_INTSTAT_GENAD_M 0x00000010 +#define AM_REG_IOSLAVE_INTSTAT_GENAD(n) (((uint32_t)(n) << 4) & 0x00000010) + +// FIFO Read Error interrupt. +#define AM_REG_IOSLAVE_INTSTAT_FRDERR_S 3 +#define AM_REG_IOSLAVE_INTSTAT_FRDERR_M 0x00000008 +#define AM_REG_IOSLAVE_INTSTAT_FRDERR(n) (((uint32_t)(n) << 3) & 0x00000008) + +// FIFO Underflow interrupt. +#define AM_REG_IOSLAVE_INTSTAT_FUNDFL_S 2 +#define AM_REG_IOSLAVE_INTSTAT_FUNDFL_M 0x00000004 +#define AM_REG_IOSLAVE_INTSTAT_FUNDFL(n) (((uint32_t)(n) << 2) & 0x00000004) + +// FIFO Overflow interrupt. +#define AM_REG_IOSLAVE_INTSTAT_FOVFL_S 1 +#define AM_REG_IOSLAVE_INTSTAT_FOVFL_M 0x00000002 +#define AM_REG_IOSLAVE_INTSTAT_FOVFL(n) (((uint32_t)(n) << 1) & 0x00000002) + +// FIFO Size interrupt. +#define AM_REG_IOSLAVE_INTSTAT_FSIZE_S 0 +#define AM_REG_IOSLAVE_INTSTAT_FSIZE_M 0x00000001 +#define AM_REG_IOSLAVE_INTSTAT_FSIZE(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// IOSLAVE_INTCLR - IO Slave Interrupts: Clear +// +//***************************************************************************** +// Transfer complete interrupt, write to register space. +#define AM_REG_IOSLAVE_INTCLR_XCMPWR_S 9 +#define AM_REG_IOSLAVE_INTCLR_XCMPWR_M 0x00000200 +#define AM_REG_IOSLAVE_INTCLR_XCMPWR(n) (((uint32_t)(n) << 9) & 0x00000200) + +// Transfer complete interrupt, write to FIFO space. +#define AM_REG_IOSLAVE_INTCLR_XCMPWF_S 8 +#define AM_REG_IOSLAVE_INTCLR_XCMPWF_M 0x00000100 +#define AM_REG_IOSLAVE_INTCLR_XCMPWF(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Transfer complete interrupt, read from register space. +#define AM_REG_IOSLAVE_INTCLR_XCMPRR_S 7 +#define AM_REG_IOSLAVE_INTCLR_XCMPRR_M 0x00000080 +#define AM_REG_IOSLAVE_INTCLR_XCMPRR(n) (((uint32_t)(n) << 7) & 0x00000080) + +// Transfer complete interrupt, read from FIFO space. +#define AM_REG_IOSLAVE_INTCLR_XCMPRF_S 6 +#define AM_REG_IOSLAVE_INTCLR_XCMPRF_M 0x00000040 +#define AM_REG_IOSLAVE_INTCLR_XCMPRF(n) (((uint32_t)(n) << 6) & 0x00000040) + +// I2C Interrupt Write interrupt. +#define AM_REG_IOSLAVE_INTCLR_IOINTW_S 5 +#define AM_REG_IOSLAVE_INTCLR_IOINTW_M 0x00000020 +#define AM_REG_IOSLAVE_INTCLR_IOINTW(n) (((uint32_t)(n) << 5) & 0x00000020) + +// I2C General Address interrupt. +#define AM_REG_IOSLAVE_INTCLR_GENAD_S 4 +#define AM_REG_IOSLAVE_INTCLR_GENAD_M 0x00000010 +#define AM_REG_IOSLAVE_INTCLR_GENAD(n) (((uint32_t)(n) << 4) & 0x00000010) + +// FIFO Read Error interrupt. +#define AM_REG_IOSLAVE_INTCLR_FRDERR_S 3 +#define AM_REG_IOSLAVE_INTCLR_FRDERR_M 0x00000008 +#define AM_REG_IOSLAVE_INTCLR_FRDERR(n) (((uint32_t)(n) << 3) & 0x00000008) + +// FIFO Underflow interrupt. +#define AM_REG_IOSLAVE_INTCLR_FUNDFL_S 2 +#define AM_REG_IOSLAVE_INTCLR_FUNDFL_M 0x00000004 +#define AM_REG_IOSLAVE_INTCLR_FUNDFL(n) (((uint32_t)(n) << 2) & 0x00000004) + +// FIFO Overflow interrupt. +#define AM_REG_IOSLAVE_INTCLR_FOVFL_S 1 +#define AM_REG_IOSLAVE_INTCLR_FOVFL_M 0x00000002 +#define AM_REG_IOSLAVE_INTCLR_FOVFL(n) (((uint32_t)(n) << 1) & 0x00000002) + +// FIFO Size interrupt. +#define AM_REG_IOSLAVE_INTCLR_FSIZE_S 0 +#define AM_REG_IOSLAVE_INTCLR_FSIZE_M 0x00000001 +#define AM_REG_IOSLAVE_INTCLR_FSIZE(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// IOSLAVE_INTSET - IO Slave Interrupts: Set +// +//***************************************************************************** +// Transfer complete interrupt, write to register space. +#define AM_REG_IOSLAVE_INTSET_XCMPWR_S 9 +#define AM_REG_IOSLAVE_INTSET_XCMPWR_M 0x00000200 +#define AM_REG_IOSLAVE_INTSET_XCMPWR(n) (((uint32_t)(n) << 9) & 0x00000200) + +// Transfer complete interrupt, write to FIFO space. +#define AM_REG_IOSLAVE_INTSET_XCMPWF_S 8 +#define AM_REG_IOSLAVE_INTSET_XCMPWF_M 0x00000100 +#define AM_REG_IOSLAVE_INTSET_XCMPWF(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Transfer complete interrupt, read from register space. +#define AM_REG_IOSLAVE_INTSET_XCMPRR_S 7 +#define AM_REG_IOSLAVE_INTSET_XCMPRR_M 0x00000080 +#define AM_REG_IOSLAVE_INTSET_XCMPRR(n) (((uint32_t)(n) << 7) & 0x00000080) + +// Transfer complete interrupt, read from FIFO space. +#define AM_REG_IOSLAVE_INTSET_XCMPRF_S 6 +#define AM_REG_IOSLAVE_INTSET_XCMPRF_M 0x00000040 +#define AM_REG_IOSLAVE_INTSET_XCMPRF(n) (((uint32_t)(n) << 6) & 0x00000040) + +// I2C Interrupt Write interrupt. +#define AM_REG_IOSLAVE_INTSET_IOINTW_S 5 +#define AM_REG_IOSLAVE_INTSET_IOINTW_M 0x00000020 +#define AM_REG_IOSLAVE_INTSET_IOINTW(n) (((uint32_t)(n) << 5) & 0x00000020) + +// I2C General Address interrupt. +#define AM_REG_IOSLAVE_INTSET_GENAD_S 4 +#define AM_REG_IOSLAVE_INTSET_GENAD_M 0x00000010 +#define AM_REG_IOSLAVE_INTSET_GENAD(n) (((uint32_t)(n) << 4) & 0x00000010) + +// FIFO Read Error interrupt. +#define AM_REG_IOSLAVE_INTSET_FRDERR_S 3 +#define AM_REG_IOSLAVE_INTSET_FRDERR_M 0x00000008 +#define AM_REG_IOSLAVE_INTSET_FRDERR(n) (((uint32_t)(n) << 3) & 0x00000008) + +// FIFO Underflow interrupt. +#define AM_REG_IOSLAVE_INTSET_FUNDFL_S 2 +#define AM_REG_IOSLAVE_INTSET_FUNDFL_M 0x00000004 +#define AM_REG_IOSLAVE_INTSET_FUNDFL(n) (((uint32_t)(n) << 2) & 0x00000004) + +// FIFO Overflow interrupt. +#define AM_REG_IOSLAVE_INTSET_FOVFL_S 1 +#define AM_REG_IOSLAVE_INTSET_FOVFL_M 0x00000002 +#define AM_REG_IOSLAVE_INTSET_FOVFL(n) (((uint32_t)(n) << 1) & 0x00000002) + +// FIFO Size interrupt. +#define AM_REG_IOSLAVE_INTSET_FSIZE_S 0 +#define AM_REG_IOSLAVE_INTSET_FSIZE_M 0x00000001 +#define AM_REG_IOSLAVE_INTSET_FSIZE(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// IOSLAVE_REGACCINTEN - Register Access Interrupts: Enable +// +//***************************************************************************** +// Register access interrupts. +#define AM_REG_IOSLAVE_REGACCINTEN_REGACC_S 0 +#define AM_REG_IOSLAVE_REGACCINTEN_REGACC_M 0xFFFFFFFF +#define AM_REG_IOSLAVE_REGACCINTEN_REGACC(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// IOSLAVE_REGACCINTSTAT - Register Access Interrupts: Status +// +//***************************************************************************** +// Register access interrupts. +#define AM_REG_IOSLAVE_REGACCINTSTAT_REGACC_S 0 +#define AM_REG_IOSLAVE_REGACCINTSTAT_REGACC_M 0xFFFFFFFF +#define AM_REG_IOSLAVE_REGACCINTSTAT_REGACC(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// IOSLAVE_REGACCINTCLR - Register Access Interrupts: Clear +// +//***************************************************************************** +// Register access interrupts. +#define AM_REG_IOSLAVE_REGACCINTCLR_REGACC_S 0 +#define AM_REG_IOSLAVE_REGACCINTCLR_REGACC_M 0xFFFFFFFF +#define AM_REG_IOSLAVE_REGACCINTCLR_REGACC(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// IOSLAVE_REGACCINTSET - Register Access Interrupts: Set +// +//***************************************************************************** +// Register access interrupts. +#define AM_REG_IOSLAVE_REGACCINTSET_REGACC_S 0 +#define AM_REG_IOSLAVE_REGACCINTSET_REGACC_M 0xFFFFFFFF +#define AM_REG_IOSLAVE_REGACCINTSET_REGACC(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// IOSLAVE_FIFOPTR - Current FIFO Pointer +// +//***************************************************************************** +// The number of bytes currently in the hardware FIFO. +#define AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S 8 +#define AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_M 0x0000FF00 +#define AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ(n) (((uint32_t)(n) << 8) & 0x0000FF00) + +// Current FIFO pointer. +#define AM_REG_IOSLAVE_FIFOPTR_FIFOPTR_S 0 +#define AM_REG_IOSLAVE_FIFOPTR_FIFOPTR_M 0x000000FF +#define AM_REG_IOSLAVE_FIFOPTR_FIFOPTR(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// IOSLAVE_FIFOCFG - FIFO Configuration +// +//***************************************************************************** +// Defines the read-only area. The IO Slave read-only area is situated in LRAM +// at (ROBASE*8) to (FIFOOBASE*8-1) +#define AM_REG_IOSLAVE_FIFOCFG_ROBASE_S 24 +#define AM_REG_IOSLAVE_FIFOCFG_ROBASE_M 0x3F000000 +#define AM_REG_IOSLAVE_FIFOCFG_ROBASE(n) (((uint32_t)(n) << 24) & 0x3F000000) + +// These bits hold the maximum FIFO address in 8 byte segments. It is also the +// beginning of the RAM area of the LRAM. Note that no RAM area is configured +// if FIFOMAX is set to 0x1F. +#define AM_REG_IOSLAVE_FIFOCFG_FIFOMAX_S 8 +#define AM_REG_IOSLAVE_FIFOCFG_FIFOMAX_M 0x00003F00 +#define AM_REG_IOSLAVE_FIFOCFG_FIFOMAX(n) (((uint32_t)(n) << 8) & 0x00003F00) + +// These bits hold the base address of the I/O FIFO in 8 byte segments. The IO +// Slave FIFO is situated in LRAM at (FIFOBASE*8) to (FIFOMAX*8-1). +#define AM_REG_IOSLAVE_FIFOCFG_FIFOBASE_S 0 +#define AM_REG_IOSLAVE_FIFOCFG_FIFOBASE_M 0x0000001F +#define AM_REG_IOSLAVE_FIFOCFG_FIFOBASE(n) (((uint32_t)(n) << 0) & 0x0000001F) + +//***************************************************************************** +// +// IOSLAVE_FIFOTHR - FIFO Threshold Configuration +// +//***************************************************************************** +// FIFO size interrupt threshold. +#define AM_REG_IOSLAVE_FIFOTHR_FIFOTHR_S 0 +#define AM_REG_IOSLAVE_FIFOTHR_FIFOTHR_M 0x000000FF +#define AM_REG_IOSLAVE_FIFOTHR_FIFOTHR(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// IOSLAVE_FUPD - FIFO Update Status +// +//***************************************************************************** +// This bitfield indicates an IO read is active. +#define AM_REG_IOSLAVE_FUPD_IOREAD_S 1 +#define AM_REG_IOSLAVE_FUPD_IOREAD_M 0x00000002 +#define AM_REG_IOSLAVE_FUPD_IOREAD(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This bit indicates that a FIFO update is underway. +#define AM_REG_IOSLAVE_FUPD_FIFOUPD_S 0 +#define AM_REG_IOSLAVE_FUPD_FIFOUPD_M 0x00000001 +#define AM_REG_IOSLAVE_FUPD_FIFOUPD(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// IOSLAVE_FIFOCTR - Overall FIFO Counter +// +//***************************************************************************** +// Virtual FIFO byte count +#define AM_REG_IOSLAVE_FIFOCTR_FIFOCTR_S 0 +#define AM_REG_IOSLAVE_FIFOCTR_FIFOCTR_M 0x000003FF +#define AM_REG_IOSLAVE_FIFOCTR_FIFOCTR(n) (((uint32_t)(n) << 0) & 0x000003FF) + +//***************************************************************************** +// +// IOSLAVE_FIFOINC - Overall FIFO Counter Increment +// +//***************************************************************************** +// Increment the Overall FIFO Counter by this value on a write +#define AM_REG_IOSLAVE_FIFOINC_FIFOINC_S 0 +#define AM_REG_IOSLAVE_FIFOINC_FIFOINC_M 0x000003FF +#define AM_REG_IOSLAVE_FIFOINC_FIFOINC(n) (((uint32_t)(n) << 0) & 0x000003FF) + +//***************************************************************************** +// +// IOSLAVE_CFG - I/O Slave Configuration +// +//***************************************************************************** +// IOSLAVE interface enable. +#define AM_REG_IOSLAVE_CFG_IFCEN_S 31 +#define AM_REG_IOSLAVE_CFG_IFCEN_M 0x80000000 +#define AM_REG_IOSLAVE_CFG_IFCEN(n) (((uint32_t)(n) << 31) & 0x80000000) +#define AM_REG_IOSLAVE_CFG_IFCEN_DIS 0x00000000 +#define AM_REG_IOSLAVE_CFG_IFCEN_EN 0x80000000 + +// 7-bit or 10-bit I2C device address. +#define AM_REG_IOSLAVE_CFG_I2CADDR_S 8 +#define AM_REG_IOSLAVE_CFG_I2CADDR_M 0x000FFF00 +#define AM_REG_IOSLAVE_CFG_I2CADDR(n) (((uint32_t)(n) << 8) & 0x000FFF00) + +// This bit holds the cycle to initiate an I/O RAM read. +#define AM_REG_IOSLAVE_CFG_STARTRD_S 4 +#define AM_REG_IOSLAVE_CFG_STARTRD_M 0x00000010 +#define AM_REG_IOSLAVE_CFG_STARTRD(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_IOSLAVE_CFG_STARTRD_LATE 0x00000000 +#define AM_REG_IOSLAVE_CFG_STARTRD_EARLY 0x00000010 + +// This bit selects the transfer bit ordering. +#define AM_REG_IOSLAVE_CFG_LSB_S 2 +#define AM_REG_IOSLAVE_CFG_LSB_M 0x00000004 +#define AM_REG_IOSLAVE_CFG_LSB(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_IOSLAVE_CFG_LSB_MSB_FIRST 0x00000000 +#define AM_REG_IOSLAVE_CFG_LSB_LSB_FIRST 0x00000004 + +// This bit selects SPI polarity. +#define AM_REG_IOSLAVE_CFG_SPOL_S 1 +#define AM_REG_IOSLAVE_CFG_SPOL_M 0x00000002 +#define AM_REG_IOSLAVE_CFG_SPOL(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_IOSLAVE_CFG_SPOL_SPI_MODES_0_3 0x00000000 +#define AM_REG_IOSLAVE_CFG_SPOL_SPI_MODES_1_2 0x00000002 + +// This bit selects the I/O interface. +#define AM_REG_IOSLAVE_CFG_IFCSEL_S 0 +#define AM_REG_IOSLAVE_CFG_IFCSEL_M 0x00000001 +#define AM_REG_IOSLAVE_CFG_IFCSEL(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_IOSLAVE_CFG_IFCSEL_I2C 0x00000000 +#define AM_REG_IOSLAVE_CFG_IFCSEL_SPI 0x00000001 + +//***************************************************************************** +// +// IOSLAVE_PRENC - I/O Slave Interrupt Priority Encode +// +//***************************************************************************** +// These bits hold the priority encode of the REGACC interrupts. +#define AM_REG_IOSLAVE_PRENC_PRENC_S 0 +#define AM_REG_IOSLAVE_PRENC_PRENC_M 0x0000001F +#define AM_REG_IOSLAVE_PRENC_PRENC(n) (((uint32_t)(n) << 0) & 0x0000001F) + +//***************************************************************************** +// +// IOSLAVE_IOINTCTL - I/O Interrupt Control +// +//***************************************************************************** +// These bits set the IOINT interrupts when written with a 1. +#define AM_REG_IOSLAVE_IOINTCTL_IOINTSET_S 24 +#define AM_REG_IOSLAVE_IOINTCTL_IOINTSET_M 0xFF000000 +#define AM_REG_IOSLAVE_IOINTCTL_IOINTSET(n) (((uint32_t)(n) << 24) & 0xFF000000) + +// This bit clears all of the IOINT interrupts when written with a 1. +#define AM_REG_IOSLAVE_IOINTCTL_IOINTCLR_S 16 +#define AM_REG_IOSLAVE_IOINTCTL_IOINTCLR_M 0x00010000 +#define AM_REG_IOSLAVE_IOINTCTL_IOINTCLR(n) (((uint32_t)(n) << 16) & 0x00010000) + +// These bits read the IOINT interrupts. +#define AM_REG_IOSLAVE_IOINTCTL_IOINT_S 8 +#define AM_REG_IOSLAVE_IOINTCTL_IOINT_M 0x0000FF00 +#define AM_REG_IOSLAVE_IOINTCTL_IOINT(n) (((uint32_t)(n) << 8) & 0x0000FF00) + +// These read-only bits indicate whether the IOINT interrupts are enabled. +#define AM_REG_IOSLAVE_IOINTCTL_IOINTEN_S 0 +#define AM_REG_IOSLAVE_IOINTCTL_IOINTEN_M 0x000000FF +#define AM_REG_IOSLAVE_IOINTCTL_IOINTEN(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// IOSLAVE_GENADD - General Address Data +// +//***************************************************************************** +// The data supplied on the last General Address reference. +#define AM_REG_IOSLAVE_GENADD_GADATA_S 0 +#define AM_REG_IOSLAVE_GENADD_GADATA_M 0x000000FF +#define AM_REG_IOSLAVE_GENADD_GADATA(n) (((uint32_t)(n) << 0) & 0x000000FF) + +#endif // AM_REG_IOSLAVE_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_itm.h b/bsp/apollo2/libraries/drivers/regs/am_reg_itm.h new file mode 100644 index 0000000000..c007aa629a --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_itm.h @@ -0,0 +1,657 @@ +//***************************************************************************** +// +// am_reg_itm.h +//! @file +//! +//! @brief Register macros for the ITM module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_ITM_H +#define AM_REG_ITM_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_ITM_NUM_MODULES 1 +#define AM_REG_ITMn(n) \ + (REG_ITM_BASEADDR + 0x00000000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_ITM_STIM0_O 0xE0000000 +#define AM_REG_ITM_STIM1_O 0xE0000004 +#define AM_REG_ITM_STIM2_O 0xE0000008 +#define AM_REG_ITM_STIM3_O 0xE000000C +#define AM_REG_ITM_STIM4_O 0xE0000010 +#define AM_REG_ITM_STIM5_O 0xE0000014 +#define AM_REG_ITM_STIM6_O 0xE0000018 +#define AM_REG_ITM_STIM7_O 0xE000001C +#define AM_REG_ITM_STIM8_O 0xE0000020 +#define AM_REG_ITM_STIM9_O 0xE0000024 +#define AM_REG_ITM_STIM10_O 0xE0000028 +#define AM_REG_ITM_STIM11_O 0xE000002C +#define AM_REG_ITM_STIM12_O 0xE0000030 +#define AM_REG_ITM_STIM13_O 0xE0000034 +#define AM_REG_ITM_STIM14_O 0xE0000038 +#define AM_REG_ITM_STIM15_O 0xE000003C +#define AM_REG_ITM_STIM16_O 0xE0000040 +#define AM_REG_ITM_STIM17_O 0xE0000044 +#define AM_REG_ITM_STIM18_O 0xE0000048 +#define AM_REG_ITM_STIM19_O 0xE000004C +#define AM_REG_ITM_STIM20_O 0xE0000050 +#define AM_REG_ITM_STIM21_O 0xE0000054 +#define AM_REG_ITM_STIM22_O 0xE0000058 +#define AM_REG_ITM_STIM23_O 0xE000005C +#define AM_REG_ITM_STIM24_O 0xE0000060 +#define AM_REG_ITM_STIM25_O 0xE0000064 +#define AM_REG_ITM_STIM26_O 0xE0000068 +#define AM_REG_ITM_STIM27_O 0xE000006C +#define AM_REG_ITM_STIM28_O 0xE0000070 +#define AM_REG_ITM_STIM29_O 0xE0000074 +#define AM_REG_ITM_STIM30_O 0xE0000078 +#define AM_REG_ITM_STIM31_O 0xE000007C +#define AM_REG_ITM_TER_O 0xE0000E00 +#define AM_REG_ITM_TPR_O 0xE0000E40 +#define AM_REG_ITM_TCR_O 0xE0000E80 +#define AM_REG_ITM_LOCKSREG_O 0xE0000FB4 +#define AM_REG_ITM_PID4_O 0xE0000FD0 +#define AM_REG_ITM_PID5_O 0xE0000FD4 +#define AM_REG_ITM_PID6_O 0xE0000FD8 +#define AM_REG_ITM_PID7_O 0xE0000FDC +#define AM_REG_ITM_PID0_O 0xE0000FE0 +#define AM_REG_ITM_PID1_O 0xE0000FE4 +#define AM_REG_ITM_PID2_O 0xE0000FE8 +#define AM_REG_ITM_PID3_O 0xE0000FEC +#define AM_REG_ITM_CID0_O 0xE0000FF0 +#define AM_REG_ITM_CID1_O 0xE0000FF4 +#define AM_REG_ITM_CID2_O 0xE0000FF8 +#define AM_REG_ITM_CID3_O 0xE0000FFC +#define AM_REG_ITM_LOCKAREG_O 0xE0000FB0 + +//***************************************************************************** +// +// Key values. +// +//***************************************************************************** +#define AM_REG_ITM_LOCKAREG_KEYVAL 0xC5ACCE55 + +//***************************************************************************** +// +// ITM_STIM0 - Stimulus Port Register 0 +// +//***************************************************************************** +// Stimulus Port Register 0. +#define AM_REG_ITM_STIM0_STIM0_S 0 +#define AM_REG_ITM_STIM0_STIM0_M 0xFFFFFFFF +#define AM_REG_ITM_STIM0_STIM0(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM1 - Stimulus Port Register 1 +// +//***************************************************************************** +// Stimulus Port Register 1. +#define AM_REG_ITM_STIM1_STIM1_S 0 +#define AM_REG_ITM_STIM1_STIM1_M 0xFFFFFFFF +#define AM_REG_ITM_STIM1_STIM1(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM2 - Stimulus Port Register 2 +// +//***************************************************************************** +// Stimulus Port Register 2. +#define AM_REG_ITM_STIM2_STIM2_S 0 +#define AM_REG_ITM_STIM2_STIM2_M 0xFFFFFFFF +#define AM_REG_ITM_STIM2_STIM2(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM3 - Stimulus Port Register 3 +// +//***************************************************************************** +// Stimulus Port Register 3. +#define AM_REG_ITM_STIM3_STIM3_S 0 +#define AM_REG_ITM_STIM3_STIM3_M 0xFFFFFFFF +#define AM_REG_ITM_STIM3_STIM3(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM4 - Stimulus Port Register 4 +// +//***************************************************************************** +// Stimulus Port Register 4. +#define AM_REG_ITM_STIM4_STIM4_S 0 +#define AM_REG_ITM_STIM4_STIM4_M 0xFFFFFFFF +#define AM_REG_ITM_STIM4_STIM4(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM5 - Stimulus Port Register 5 +// +//***************************************************************************** +// Stimulus Port Register 5. +#define AM_REG_ITM_STIM5_STIM5_S 0 +#define AM_REG_ITM_STIM5_STIM5_M 0xFFFFFFFF +#define AM_REG_ITM_STIM5_STIM5(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM6 - Stimulus Port Register 6 +// +//***************************************************************************** +// Stimulus Port Register 6. +#define AM_REG_ITM_STIM6_STIM6_S 0 +#define AM_REG_ITM_STIM6_STIM6_M 0xFFFFFFFF +#define AM_REG_ITM_STIM6_STIM6(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM7 - Stimulus Port Register 7 +// +//***************************************************************************** +// Stimulus Port Register 7. +#define AM_REG_ITM_STIM7_STIM7_S 0 +#define AM_REG_ITM_STIM7_STIM7_M 0xFFFFFFFF +#define AM_REG_ITM_STIM7_STIM7(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM8 - Stimulus Port Register 8 +// +//***************************************************************************** +// Stimulus Port Register 8. +#define AM_REG_ITM_STIM8_STIM8_S 0 +#define AM_REG_ITM_STIM8_STIM8_M 0xFFFFFFFF +#define AM_REG_ITM_STIM8_STIM8(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM9 - Stimulus Port Register 9 +// +//***************************************************************************** +// Stimulus Port Register 9. +#define AM_REG_ITM_STIM9_STIM9_S 0 +#define AM_REG_ITM_STIM9_STIM9_M 0xFFFFFFFF +#define AM_REG_ITM_STIM9_STIM9(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM10 - Stimulus Port Register 10 +// +//***************************************************************************** +// Stimulus Port Register 10. +#define AM_REG_ITM_STIM10_STIM10_S 0 +#define AM_REG_ITM_STIM10_STIM10_M 0xFFFFFFFF +#define AM_REG_ITM_STIM10_STIM10(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM11 - Stimulus Port Register 11 +// +//***************************************************************************** +// Stimulus Port Register 11. +#define AM_REG_ITM_STIM11_STIM11_S 0 +#define AM_REG_ITM_STIM11_STIM11_M 0xFFFFFFFF +#define AM_REG_ITM_STIM11_STIM11(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM12 - Stimulus Port Register 12 +// +//***************************************************************************** +// Stimulus Port Register 12. +#define AM_REG_ITM_STIM12_STIM12_S 0 +#define AM_REG_ITM_STIM12_STIM12_M 0xFFFFFFFF +#define AM_REG_ITM_STIM12_STIM12(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM13 - Stimulus Port Register 13 +// +//***************************************************************************** +// Stimulus Port Register 13. +#define AM_REG_ITM_STIM13_STIM13_S 0 +#define AM_REG_ITM_STIM13_STIM13_M 0xFFFFFFFF +#define AM_REG_ITM_STIM13_STIM13(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM14 - Stimulus Port Register 14 +// +//***************************************************************************** +// Stimulus Port Register 14. +#define AM_REG_ITM_STIM14_STIM14_S 0 +#define AM_REG_ITM_STIM14_STIM14_M 0xFFFFFFFF +#define AM_REG_ITM_STIM14_STIM14(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM15 - Stimulus Port Register 15 +// +//***************************************************************************** +// Stimulus Port Register 15. +#define AM_REG_ITM_STIM15_STIM15_S 0 +#define AM_REG_ITM_STIM15_STIM15_M 0xFFFFFFFF +#define AM_REG_ITM_STIM15_STIM15(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM16 - Stimulus Port Register 16 +// +//***************************************************************************** +// Stimulus Port Register 16. +#define AM_REG_ITM_STIM16_STIM16_S 0 +#define AM_REG_ITM_STIM16_STIM16_M 0xFFFFFFFF +#define AM_REG_ITM_STIM16_STIM16(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM17 - Stimulus Port Register 17 +// +//***************************************************************************** +// Stimulus Port Register 17. +#define AM_REG_ITM_STIM17_STIM17_S 0 +#define AM_REG_ITM_STIM17_STIM17_M 0xFFFFFFFF +#define AM_REG_ITM_STIM17_STIM17(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM18 - Stimulus Port Register 18 +// +//***************************************************************************** +// Stimulus Port Register 18. +#define AM_REG_ITM_STIM18_STIM18_S 0 +#define AM_REG_ITM_STIM18_STIM18_M 0xFFFFFFFF +#define AM_REG_ITM_STIM18_STIM18(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM19 - Stimulus Port Register 19 +// +//***************************************************************************** +// Stimulus Port Register 19. +#define AM_REG_ITM_STIM19_STIM19_S 0 +#define AM_REG_ITM_STIM19_STIM19_M 0xFFFFFFFF +#define AM_REG_ITM_STIM19_STIM19(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM20 - Stimulus Port Register 20 +// +//***************************************************************************** +// Stimulus Port Register 20. +#define AM_REG_ITM_STIM20_STIM20_S 0 +#define AM_REG_ITM_STIM20_STIM20_M 0xFFFFFFFF +#define AM_REG_ITM_STIM20_STIM20(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM21 - Stimulus Port Register 21 +// +//***************************************************************************** +// Stimulus Port Register 21. +#define AM_REG_ITM_STIM21_STIM21_S 0 +#define AM_REG_ITM_STIM21_STIM21_M 0xFFFFFFFF +#define AM_REG_ITM_STIM21_STIM21(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM22 - Stimulus Port Register 22 +// +//***************************************************************************** +// Stimulus Port Register 22. +#define AM_REG_ITM_STIM22_STIM22_S 0 +#define AM_REG_ITM_STIM22_STIM22_M 0xFFFFFFFF +#define AM_REG_ITM_STIM22_STIM22(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM23 - Stimulus Port Register 23 +// +//***************************************************************************** +// Stimulus Port Register 23. +#define AM_REG_ITM_STIM23_STIM23_S 0 +#define AM_REG_ITM_STIM23_STIM23_M 0xFFFFFFFF +#define AM_REG_ITM_STIM23_STIM23(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM24 - Stimulus Port Register 24 +// +//***************************************************************************** +// Stimulus Port Register 24. +#define AM_REG_ITM_STIM24_STIM24_S 0 +#define AM_REG_ITM_STIM24_STIM24_M 0xFFFFFFFF +#define AM_REG_ITM_STIM24_STIM24(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM25 - Stimulus Port Register 25 +// +//***************************************************************************** +// Stimulus Port Register 25. +#define AM_REG_ITM_STIM25_STIM25_S 0 +#define AM_REG_ITM_STIM25_STIM25_M 0xFFFFFFFF +#define AM_REG_ITM_STIM25_STIM25(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM26 - Stimulus Port Register 26 +// +//***************************************************************************** +// Stimulus Port Register 26. +#define AM_REG_ITM_STIM26_STIM26_S 0 +#define AM_REG_ITM_STIM26_STIM26_M 0xFFFFFFFF +#define AM_REG_ITM_STIM26_STIM26(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM27 - Stimulus Port Register 27 +// +//***************************************************************************** +// Stimulus Port Register 27. +#define AM_REG_ITM_STIM27_STIM27_S 0 +#define AM_REG_ITM_STIM27_STIM27_M 0xFFFFFFFF +#define AM_REG_ITM_STIM27_STIM27(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM28 - Stimulus Port Register 28 +// +//***************************************************************************** +// Stimulus Port Register 28. +#define AM_REG_ITM_STIM28_STIM28_S 0 +#define AM_REG_ITM_STIM28_STIM28_M 0xFFFFFFFF +#define AM_REG_ITM_STIM28_STIM28(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM29 - Stimulus Port Register 29 +// +//***************************************************************************** +// Stimulus Port Register 29. +#define AM_REG_ITM_STIM29_STIM29_S 0 +#define AM_REG_ITM_STIM29_STIM29_M 0xFFFFFFFF +#define AM_REG_ITM_STIM29_STIM29(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM30 - Stimulus Port Register 30 +// +//***************************************************************************** +// Stimulus Port Register 30. +#define AM_REG_ITM_STIM30_STIM30_S 0 +#define AM_REG_ITM_STIM30_STIM30_M 0xFFFFFFFF +#define AM_REG_ITM_STIM30_STIM30(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_STIM31 - Stimulus Port Register 31 +// +//***************************************************************************** +// Stimulus Port Register 31. +#define AM_REG_ITM_STIM31_STIM31_S 0 +#define AM_REG_ITM_STIM31_STIM31_M 0xFFFFFFFF +#define AM_REG_ITM_STIM31_STIM31(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_TER - Trace Enable Register. +// +//***************************************************************************** +// Bit mask to enable tracing on ITM stimulus ports. One bit per stimulus port.. +#define AM_REG_ITM_TER_STIMENA_S 0 +#define AM_REG_ITM_TER_STIMENA_M 0xFFFFFFFF +#define AM_REG_ITM_TER_STIMENA(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_TPR - Trace Privilege Register. +// +//***************************************************************************** +// Bit mask to enable tracing on ITM stimulus ports. bit[0] = stimulus +// ports[7:0], bit[1] = stimulus ports[15:8], bit[2] = stimulus ports[23:16], +// bit[3] = stimulus ports[31:24]. +#define AM_REG_ITM_TPR_PRIVMASK_S 0 +#define AM_REG_ITM_TPR_PRIVMASK_M 0x0000000F +#define AM_REG_ITM_TPR_PRIVMASK(n) (((uint32_t)(n) << 0) & 0x0000000F) + +//***************************************************************************** +// +// ITM_TCR - Trace Control Register. +// +//***************************************************************************** +// Set when ITM events present and being drained. +#define AM_REG_ITM_TCR_BUSY_S 23 +#define AM_REG_ITM_TCR_BUSY_M 0x00800000 +#define AM_REG_ITM_TCR_BUSY(n) (((uint32_t)(n) << 23) & 0x00800000) + +// ATB ID for CoreSight system. +#define AM_REG_ITM_TCR_ATB_ID_S 16 +#define AM_REG_ITM_TCR_ATB_ID_M 0x007F0000 +#define AM_REG_ITM_TCR_ATB_ID(n) (((uint32_t)(n) << 16) & 0x007F0000) + +// Global Timestamp Frequency. +#define AM_REG_ITM_TCR_TS_FREQ_S 10 +#define AM_REG_ITM_TCR_TS_FREQ_M 0x00000C00 +#define AM_REG_ITM_TCR_TS_FREQ(n) (((uint32_t)(n) << 10) & 0x00000C00) + +// Timestamp prescaler: 0b00 = no prescaling 0b01 = divide by 4 0b10 = divide by +// 16 0b11 = divide by 64. +#define AM_REG_ITM_TCR_TS_PRESCALE_S 8 +#define AM_REG_ITM_TCR_TS_PRESCALE_M 0x00000300 +#define AM_REG_ITM_TCR_TS_PRESCALE(n) (((uint32_t)(n) << 8) & 0x00000300) + +// Enable SWV behavior – count on TPIUEMIT and TPIUBAUD. +#define AM_REG_ITM_TCR_SWV_ENABLE_S 4 +#define AM_REG_ITM_TCR_SWV_ENABLE_M 0x00000010 +#define AM_REG_ITM_TCR_SWV_ENABLE(n) (((uint32_t)(n) << 4) & 0x00000010) + +// Enables the DWT stimulus. +#define AM_REG_ITM_TCR_DWT_ENABLE_S 3 +#define AM_REG_ITM_TCR_DWT_ENABLE_M 0x00000008 +#define AM_REG_ITM_TCR_DWT_ENABLE(n) (((uint32_t)(n) << 3) & 0x00000008) + +// Enables sync packets for TPIU. +#define AM_REG_ITM_TCR_SYNC_ENABLE_S 2 +#define AM_REG_ITM_TCR_SYNC_ENABLE_M 0x00000004 +#define AM_REG_ITM_TCR_SYNC_ENABLE(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Enables differential timestamps. Differential timestamps are emitted when a +// packet is written to the FIFO with a non-zero timestamp counter, and when the +// timestamp counter overflows. Timestamps are emitted during idle times after a +// fixed number of cycles. This provides a time reference for packets and inter- +// packet gaps. +#define AM_REG_ITM_TCR_TS_ENABLE_S 1 +#define AM_REG_ITM_TCR_TS_ENABLE_M 0x00000002 +#define AM_REG_ITM_TCR_TS_ENABLE(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Enable ITM. This is the master enable, and must be set before ITM Stimulus +// and Trace Enable registers can be written. +#define AM_REG_ITM_TCR_ITM_ENABLE_S 0 +#define AM_REG_ITM_TCR_ITM_ENABLE_M 0x00000001 +#define AM_REG_ITM_TCR_ITM_ENABLE(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// ITM_LOCKSREG - Lock Status Register +// +//***************************************************************************** +// You cannot implement 8-bit lock accesses. +#define AM_REG_ITM_LOCKSREG_BYTEACC_S 2 +#define AM_REG_ITM_LOCKSREG_BYTEACC_M 0x00000004 +#define AM_REG_ITM_LOCKSREG_BYTEACC(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Write access to component is blocked. All writes are ignored, reads are +// permitted. +#define AM_REG_ITM_LOCKSREG_ACCESS_S 1 +#define AM_REG_ITM_LOCKSREG_ACCESS_M 0x00000002 +#define AM_REG_ITM_LOCKSREG_ACCESS(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Indicates that a lock mechanism exists for this component. +#define AM_REG_ITM_LOCKSREG_PRESENT_S 0 +#define AM_REG_ITM_LOCKSREG_PRESENT_M 0x00000001 +#define AM_REG_ITM_LOCKSREG_PRESENT(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// ITM_PID4 - Peripheral Identification Register 4 +// +//***************************************************************************** +// Peripheral Identification 4. +#define AM_REG_ITM_PID4_PID4_S 0 +#define AM_REG_ITM_PID4_PID4_M 0xFFFFFFFF +#define AM_REG_ITM_PID4_PID4(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_PID5 - Peripheral Identification Register 5 +// +//***************************************************************************** +// Peripheral Identification 5. +#define AM_REG_ITM_PID5_PID5_S 0 +#define AM_REG_ITM_PID5_PID5_M 0xFFFFFFFF +#define AM_REG_ITM_PID5_PID5(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_PID6 - Peripheral Identification Register 6 +// +//***************************************************************************** +// Peripheral Identification 6. +#define AM_REG_ITM_PID6_PID6_S 0 +#define AM_REG_ITM_PID6_PID6_M 0xFFFFFFFF +#define AM_REG_ITM_PID6_PID6(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_PID7 - Peripheral Identification Register 7 +// +//***************************************************************************** +// Peripheral Identification 7. +#define AM_REG_ITM_PID7_PID7_S 0 +#define AM_REG_ITM_PID7_PID7_M 0xFFFFFFFF +#define AM_REG_ITM_PID7_PID7(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_PID0 - Peripheral Identification Register 0 +// +//***************************************************************************** +// Peripheral Identification 0. +#define AM_REG_ITM_PID0_PID0_S 0 +#define AM_REG_ITM_PID0_PID0_M 0xFFFFFFFF +#define AM_REG_ITM_PID0_PID0(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_PID1 - Peripheral Identification Register 1 +// +//***************************************************************************** +// Peripheral Identification 1. +#define AM_REG_ITM_PID1_PID1_S 0 +#define AM_REG_ITM_PID1_PID1_M 0xFFFFFFFF +#define AM_REG_ITM_PID1_PID1(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_PID2 - Peripheral Identification Register 2 +// +//***************************************************************************** +// Peripheral Identification 2. +#define AM_REG_ITM_PID2_PID2_S 0 +#define AM_REG_ITM_PID2_PID2_M 0xFFFFFFFF +#define AM_REG_ITM_PID2_PID2(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_PID3 - Peripheral Identification Register 3 +// +//***************************************************************************** +// Peripheral Identification 3. +#define AM_REG_ITM_PID3_PID3_S 0 +#define AM_REG_ITM_PID3_PID3_M 0xFFFFFFFF +#define AM_REG_ITM_PID3_PID3(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_CID0 - Component Identification Register 1 +// +//***************************************************************************** +// Component Identification 1. +#define AM_REG_ITM_CID0_CID0_S 0 +#define AM_REG_ITM_CID0_CID0_M 0xFFFFFFFF +#define AM_REG_ITM_CID0_CID0(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_CID1 - Component Identification Register 1 +// +//***************************************************************************** +// Component Identification 1. +#define AM_REG_ITM_CID1_CID1_S 0 +#define AM_REG_ITM_CID1_CID1_M 0xFFFFFFFF +#define AM_REG_ITM_CID1_CID1(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_CID2 - Component Identification Register 2 +// +//***************************************************************************** +// Component Identification 2. +#define AM_REG_ITM_CID2_CID2_S 0 +#define AM_REG_ITM_CID2_CID2_M 0xFFFFFFFF +#define AM_REG_ITM_CID2_CID2(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// ITM_CID3 - Component Identification Register 3 +// +//***************************************************************************** +// Component Identification 3. +#define AM_REG_ITM_CID3_CID3_S 0 +#define AM_REG_ITM_CID3_CID3_M 0xFFFFFFFF +#define AM_REG_ITM_CID3_CID3(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +#endif // AM_REG_ITM_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_jedec.h b/bsp/apollo2/libraries/drivers/regs/am_reg_jedec.h new file mode 100644 index 0000000000..61560dc099 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_jedec.h @@ -0,0 +1,215 @@ +//***************************************************************************** +// +// am_reg_jedec.h +//! @file +//! +//! @brief Register macros for the JEDEC module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_JEDEC_H +#define AM_REG_JEDEC_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_JEDEC_NUM_MODULES 1 +#define AM_REG_JEDECn(n) \ + (REG_JEDEC_BASEADDR + 0x00000000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_JEDEC_PID4_O 0xF0000FD0 +#define AM_REG_JEDEC_PID5_O 0xF0000FD4 +#define AM_REG_JEDEC_PID6_O 0xF0000FD8 +#define AM_REG_JEDEC_PID7_O 0xF0000FDC +#define AM_REG_JEDEC_PID0_O 0xF0000FE0 +#define AM_REG_JEDEC_PID1_O 0xF0000FE4 +#define AM_REG_JEDEC_PID2_O 0xF0000FE8 +#define AM_REG_JEDEC_PID3_O 0xF0000FEC +#define AM_REG_JEDEC_CID0_O 0xF0000FF0 +#define AM_REG_JEDEC_CID1_O 0xF0000FF4 +#define AM_REG_JEDEC_CID2_O 0xF0000FF8 +#define AM_REG_JEDEC_CID3_O 0xF0000FFC + +//***************************************************************************** +// +// JEDEC_PID4 - JEP Continuation Register +// +//***************************************************************************** +// Contains the JEP Continuation bits. +#define AM_REG_JEDEC_PID4_JEPCONT_S 0 +#define AM_REG_JEDEC_PID4_JEPCONT_M 0x0000000F +#define AM_REG_JEDEC_PID4_JEPCONT(n) (((uint32_t)(n) << 0) & 0x0000000F) + +//***************************************************************************** +// +// JEDEC_PID5 - JEP reserved Register +// +//***************************************************************************** +// Contains the value of 0x00000000. +#define AM_REG_JEDEC_PID5_VALUE_S 0 +#define AM_REG_JEDEC_PID5_VALUE_M 0xFFFFFFFF +#define AM_REG_JEDEC_PID5_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// JEDEC_PID6 - JEP reserved Register +// +//***************************************************************************** +// Contains the value of 0x00000000. +#define AM_REG_JEDEC_PID6_VALUE_S 0 +#define AM_REG_JEDEC_PID6_VALUE_M 0xFFFFFFFF +#define AM_REG_JEDEC_PID6_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// JEDEC_PID7 - JEP reserved Register +// +//***************************************************************************** +// Contains the value of 0x00000000. +#define AM_REG_JEDEC_PID7_VALUE_S 0 +#define AM_REG_JEDEC_PID7_VALUE_M 0xFFFFFFFF +#define AM_REG_JEDEC_PID7_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// JEDEC_PID0 - Ambiq Partnum low byte +// +//***************************************************************************** +// Contains the low 8 bits of the Ambiq Micro device part number. +#define AM_REG_JEDEC_PID0_PNL8_S 0 +#define AM_REG_JEDEC_PID0_PNL8_M 0x000000FF +#define AM_REG_JEDEC_PID0_PNL8(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// JEDEC_PID1 - Ambiq part number high-nibble, JEPID low-nibble. +// +//***************************************************************************** +// Contains the low 4 bits of the Ambiq Micro JEDEC JEP-106 ID. The full JEPID +// is therefore 0x9B. +#define AM_REG_JEDEC_PID1_JEPIDL_S 4 +#define AM_REG_JEDEC_PID1_JEPIDL_M 0x000000F0 +#define AM_REG_JEDEC_PID1_JEPIDL(n) (((uint32_t)(n) << 4) & 0x000000F0) + +// Contains the high 4 bits of the Ambiq Micro device part number. +#define AM_REG_JEDEC_PID1_PNH4_S 0 +#define AM_REG_JEDEC_PID1_PNH4_M 0x0000000F +#define AM_REG_JEDEC_PID1_PNH4(n) (((uint32_t)(n) << 0) & 0x0000000F) + +//***************************************************************************** +// +// JEDEC_PID2 - Ambiq chip revision low-nibble, JEPID high-nibble +// +//***************************************************************************** +// Contains the high 4 bits of the Ambiq Micro CHIPREV (see also +// MCUCTRL.CHIPREV). Note that this field will change with each revision of the +// chip. +#define AM_REG_JEDEC_PID2_CHIPREVH4_S 4 +#define AM_REG_JEDEC_PID2_CHIPREVH4_M 0x000000F0 +#define AM_REG_JEDEC_PID2_CHIPREVH4(n) (((uint32_t)(n) << 4) & 0x000000F0) + +// Contains the high 3 bits of the Ambiq Micro JEPID. Note that bit3 of this +// field is hard-coded to 1. The full JEPID is therefore 0x9B. +#define AM_REG_JEDEC_PID2_JEPIDH_S 0 +#define AM_REG_JEDEC_PID2_JEPIDH_M 0x0000000F +#define AM_REG_JEDEC_PID2_JEPIDH(n) (((uint32_t)(n) << 0) & 0x0000000F) + +//***************************************************************************** +// +// JEDEC_PID3 - Ambiq chip revision high-nibble. +// +//***************************************************************************** +// Contains the low 4 bits of the Ambiq Micro CHIPREV (see also +// MCUCTRL.CHIPREV). Note that this field will change with each revision of the +// chip. +#define AM_REG_JEDEC_PID3_CHIPREVL4_S 4 +#define AM_REG_JEDEC_PID3_CHIPREVL4_M 0x000000F0 +#define AM_REG_JEDEC_PID3_CHIPREVL4(n) (((uint32_t)(n) << 4) & 0x000000F0) + +// This field is hard-coded to 0x0. +#define AM_REG_JEDEC_PID3_ZERO_S 0 +#define AM_REG_JEDEC_PID3_ZERO_M 0x0000000F +#define AM_REG_JEDEC_PID3_ZERO(n) (((uint32_t)(n) << 0) & 0x0000000F) + +//***************************************************************************** +// +// JEDEC_CID0 - Coresight ROM Table. +// +//***************************************************************************** +// Coresight ROM Table, CID0. +#define AM_REG_JEDEC_CID0_CID_S 0 +#define AM_REG_JEDEC_CID0_CID_M 0x000000FF +#define AM_REG_JEDEC_CID0_CID(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// JEDEC_CID1 - Coresight ROM Table. +// +//***************************************************************************** +// Coresight ROM Table, CID1. +#define AM_REG_JEDEC_CID1_CID_S 0 +#define AM_REG_JEDEC_CID1_CID_M 0x000000FF +#define AM_REG_JEDEC_CID1_CID(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// JEDEC_CID2 - Coresight ROM Table. +// +//***************************************************************************** +// Coresight ROM Table, CID2. +#define AM_REG_JEDEC_CID2_CID_S 0 +#define AM_REG_JEDEC_CID2_CID_M 0x000000FF +#define AM_REG_JEDEC_CID2_CID(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// JEDEC_CID3 - Coresight ROM Table. +// +//***************************************************************************** +// Coresight ROM Table, CID3. +#define AM_REG_JEDEC_CID3_CID_S 0 +#define AM_REG_JEDEC_CID3_CID_M 0x000000FF +#define AM_REG_JEDEC_CID3_CID(n) (((uint32_t)(n) << 0) & 0x000000FF) + +#endif // AM_REG_JEDEC_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_macros.h b/bsp/apollo2/libraries/drivers/regs/am_reg_macros.h new file mode 100644 index 0000000000..e9662958c1 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_macros.h @@ -0,0 +1,312 @@ +//***************************************************************************** +// +//! @file am_reg_macros.h +//! +//! @brief Helper macros for using hardware registers. +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#ifndef AM_REG_MACROS_H +#define AM_REG_MACROS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Include the inline assembly macros. +// +//***************************************************************************** +#include "am_reg_macros_asm.h" + +//***************************************************************************** +// +// High-level Helper Macros. +// +// Usage: +// +// For direct 32-bit access to a register, use AM_REGVAL: +// AM_REGVAL(REG_VCOMP_BASEADDR + AM_VCOMP_VCMPCFG_O) |= 0xDEADBEEF; +// +// The AM_REG macro can also be used as a shorthand version of AM_REGVAL: +// AM_REG(VCOMP, VCMPCFG) |= 0xDEADBEEF; +// +// The AM_REGn macro is used for accessing registers of peripherals with +// multiple instances, such as IOMSTR. +// AM_REGn(IOMSTR, 1, CLKCFG) |= 0xDEADBEEF; +// +// To write to a specific bitfield within a register, use AM_BFW or AM_BFWn: +// AM_BFW(CTIMER, 0, CTCTRL0, TMRB0FN, 0x3); +// +// To read a field, use AM_BFR or AM_BFRn: +// ui32Timer0Fn = AM_BFR((CTIMER, 0, CTCTRL0, TMRB0FN); +// +// Note: +// +// AM_REGn, AM_BFW and AM_BFR are concatenation-based, which means that +// standalone macro definitions should not be used for the 'module', 'reg', and +// 'field' arguments.All macro names in the various peripheral header files are +// written in one of the following forms: +// - AM_REG_##module_reg_O +// - AM_REG_##module_reg_field_S +// - AM_REG_##module_reg_field_M +// +// The "module", "reg" and "field" fragments may be used as valid arguments to +// the AM_REGn, AM_BFW, and AM_BFR macros, all of which are able to perform the +// necessary concatenation operations to reconstruct the full macros and look +// up the appropriate base address for the instance number given. For +// peripherals with only one instance, use instance number 0. +// +// The AM_REGVAL macro does not perform any concatenation operations, so the +// complete macro name (including any suffix) must be specified. +// +//***************************************************************************** +#define AM_REGVAL(x) (*((volatile uint32_t *)(x))) +#define AM_REGVAL_FLOAT(x) (*((volatile float *)(x))) + +//***************************************************************************** +// +// Register access macros for single-instance modules +// AM_REG - Write a register of a module. +// AM_BFW - Write a value to a bitfield of a register. +// AM_BFWe - Use a defined enum value to write a value to a bitfield. +// AM_BFR - Read a bitfield value from a register. +// AM_BFM - Read and mask a bitfield, but leave the value in its bit position. +// (Useful for comparing with enums.) +// +//***************************************************************************** +#define AM_REG(module, reg) \ + AM_REGn(module, 0, reg) + +#define AM_BFW(module, reg, field, value) \ + AM_BFWn(module, 0, reg, field, value) + +#define AM_BFWe(module, reg, field, enumval) \ + AM_BFWen(module, 0, reg, field, enumval) + +#define AM_BFR(module, reg, field) \ + AM_BFRn(module, 0, reg, field) + +#define AM_BFM(module, reg, field) \ + AM_BFMn(module, 0, reg, field) + +#define AM_BFV(module, reg, field, value) \ + (((uint32_t)(value) << AM_REG_##module##_##reg##_##field##_S) & \ + AM_REG_##module##_##reg##_##field##_M) + +#define AM_BFX(module, reg, field, value) \ + (((uint32_t)(value) & AM_REG_##module##_##reg##_##field##_M) >> \ + AM_REG_##module##_##reg##_##field##_S) + + +//***************************************************************************** +// +// Register access macros for multi-instance modules +// AM_REGn - Write a register of a multiple instance module. +// AM_BFWn - Write a value to a bitfield of a register in a multiple instance. +// AM_BFWen - Use a defined enum value to write a value to a bitfield of a +// register in a multiple instance. +// AM_BFRn - Read a bitfield value from a register in a multiple instance. +// AM_BFMn - Read a bitfield, but leave the value in its bitfield position. +// AM_BFMn - Read and mask a bitfield, but leave the value in its bit position. +// (Useful for comparing with enums.) +// +//***************************************************************************** +#define AM_REGn(module, instance, reg) \ + AM_REGVAL(AM_REG_##module##n(instance) + AM_REG_##module##_##reg##_O) + +#define AM_BFWn(module, instance, reg, field, value) \ + AM_REGn(module, instance, reg) = \ + (AM_BFV(module, reg, field, value) | \ + (AM_REGn(module, instance, reg) & \ + (~AM_REG_##module##_##reg##_##field##_M))) + +#define AM_BFWen(module, instance, reg, field, enumval) \ + AM_REGn(module, instance, reg) = \ + (AM_REG_##module##_##reg##_##field##_##enumval | \ + (AM_REGn(module, instance, reg) & \ + (~AM_REG_##module##_##reg##_##field##_M))) + +#define AM_BFRn(module, instance, reg, field) \ + AM_BFX(module, reg, field, AM_REGn(module, instance, reg)) + +#define AM_BFMn(module, instance, reg, field) \ + (AM_REGn(module, instance, reg) & AM_REG_##module##_##reg##_##field##_M) + +//***************************************************************************** +// +// "Atomic" register access macros - use when a read-modify-write is required. +// +// These macros will be slower than the normal macros, but they will also +// guarantee threadsafe hardware access. +// +// These macros require a nesting-friendly critical section implementation. If +// you are using the HAL, you can use the default definitions below. If not, +// you will need to supply your own. +// +// Atomic register access macros usage: +// AM_REGa - Write a register of a single instance module. Provide operator +// (&,|,etc) to perform that operation on the reg using value, or +// no operator to simply write the value atomically. +// AM_REGa_SET - Set bits in a single instance module according to the mask. +// AM_REGa_CLR - Clear bits in a single instance module according to the mask. +// AM_REGna - Multiple module version of AM_REGa. +// AM_REGna_SET - Multiple instance version of AM_REGa_SET. +// AM_REGna_CLR - Multiple instance version of AM_REGa_CLR. +// AM_BFWa - Write a value to a register bitfield. +// AM_BFWae - Use a defined enum value to write a value to a bitfield. +// AM_BFWan - Write a value to a bitfield of a register in a multiple instance. +// AM_BFWaen - Use a defined enum value to write a value to a bitfield of a +// register in a multiple instance. +// +//***************************************************************************** +#ifndef AM_CRITICAL_BEGIN +#define AM_CRITICAL_BEGIN uint32_t ui32Primask = am_hal_interrupt_master_disable() +#define AM_CRITICAL_END am_hal_interrupt_master_set(ui32Primask) +#endif + +#define AM_REGan(module, instance, reg, operator, value) \ + AM_CRITICAL_BEGIN_ASM \ + AM_REGn(module, instance, reg) operator##= (value); \ + AM_CRITICAL_END_ASM + +#define AM_REGan_SET(module, instance, reg, mask) \ + AM_CRITICAL_BEGIN_ASM \ + AM_REGn(module, instance, reg) |= (mask); \ + AM_CRITICAL_END_ASM + +#define AM_REGan_CLR(module, instance, reg, mask) \ + AM_CRITICAL_BEGIN_ASM \ + AM_REGn(module, instance, reg) &= (~mask); \ + AM_CRITICAL_END_ASM + +#define AM_REGa(module, reg, operator, value) \ + AM_REGan(module, 0, reg, operator, value) + +#define AM_REGa_CLR(module, reg, mask) \ + AM_REGan_CLR(module, 0, reg, mask) + +#define AM_REGa_SET(module, reg, mask) \ + AM_REGan_SET(module, 0, reg, mask) + +#define AM_BFWa(module, reg, field, value) \ + AM_CRITICAL_BEGIN_ASM \ + AM_BFW(module, reg, field, value); \ + AM_CRITICAL_END_ASM + +#define AM_BFWae(module, reg, field, enumval) \ + AM_CRITICAL_BEGIN_ASM \ + AM_BFWe(module, reg, field, enumval); \ + AM_CRITICAL_END_ASM + +#define AM_BFWan(module, instance, reg, field, value) \ + AM_CRITICAL_BEGIN_ASM \ + AM_BFWn(module, instance, reg, field, enumval); \ + AM_CRITICAL_END_ASM + +#define AM_BFWaen(module, instance, reg, field, enumval) \ + AM_CRITICAL_BEGIN_ASM \ + AM_BFWen(module, instance reg, field, enumval); \ + AM_CRITICAL_END_ASM + +//***************************************************************************** +// +// Other helper Macros. +// +// Note: These macros make use of macro concatenation, so the '_S' or '_M' +// suffix on a register bitfield macro should not be supplied by the user. +// The macro will apply each suffix as needed. +// +//***************************************************************************** + +// +// AM_ENUMX extracts a register bitfield enumeration to the bit 0 position, +// which makes it possible to use enums directly with existing macros such +// as AM_BFR() or AM_BFW(). +// Brief overview: bitfield enumerations are pre-shifted such that the defined +// value lines up with the bitfield. This is convenient for many operations, +// but not so when using AM_BFR() to read the value of a register bitfield +// as AM_BFR() shifts the bitfield value to the bit 0 position. +// Note that this type of bitfield extraction is Cortex efficient via the +// UBFX (unsigned bit field extract) instruction. +// +// Alternately, AM_BFM() can also be used. AM_BFM() reads a register and masks +// the bitfield value (without shifting), thereby allowing direct comparison +// with a defined enum. +// +// Examples: +// if ( AM_BFR(CLKGEN, CCTRL, CORESEL) == +// AM_ENUMX(CLKGEN, CCTRL, CORESEL, HFRC) ) +// +// or alternatively: +// if ( AM_BFM(CLKGEN, CCTRL, CORESEL) == AM_REG_CLKGEN_CCTRL_CORESEL_HFRC ) +// +#define AM_ENUMX(module, reg, field, enumname) \ + ((AM_REG_##module##_##reg##_##field##_##enumname) >> \ + (AM_REG_##module##_##reg##_##field##_S)) + +// +// AM_WRITE_SM performs a shift/mask operation to prepare the value 'x' to be +// written to the register field 'field'. +// +// For example: +// AM_REGVAL(ui32Base + AM_VCOMP_VCMP_CFG_O) |= +// AM_WRITE_SM(AM_VCOMP_VCMP_CFG_LVLSEL, ui32Value); +// +#define AM_WRITE_SM(field, x) (((x) << field##_S) & field##_M) + +// +// AM_READ_SM performs a shift/mask operation to make it easier to interpret +// the value of a given bitfield. This is essentially the reverse of the +// AM_WRITE_SM operation. In most cases, you will want to use the shorter +// AM_BFR macro instead of this one. +// +// For example: +// ui32Value = AM_READ_SM(AM_VCOMP_VCMP_CFG_NSEL, +// AM_REGVAL(ui32Base + AM_VCOMP_VCMP_CFG_O)); +// +#define AM_READ_SM(field, x) (((x) & field##_M) >> field##_S) + +#ifdef __cplusplus +} +#endif + +#endif // AM_REG_MACROS_H + diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_macros_asm.h b/bsp/apollo2/libraries/drivers/regs/am_reg_macros_asm.h new file mode 100644 index 0000000000..f02624d8e3 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_macros_asm.h @@ -0,0 +1,162 @@ +//***************************************************************************** +// +//! @file am_reg_macros_asm.h +//! +//! @brief Inline assembly macros. Initially for critical section handling in +//! protecting hardware registers. +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#ifndef AM_REG_MACROS_ASM_H +#define AM_REG_MACROS_ASM_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Critical section assembly macros +// +// These macros implement critical section protection using inline assembly +// for various compilers. They are intended to be used in other register +// macros or directly in sections of code. +// +// Important usage note: These macros create a local scope and therefore MUST +// be used in pairs. +// +//***************************************************************************** + +#if defined(__GNUC_STDC_INLINE__) +// +// GCC macros. +// +#define AM_CRITICAL_BEGIN_ASM \ + if ( 1 ) \ + { \ + volatile uint32_t ui32Primask_04172010; \ + __asm(" mrs %0, PRIMASK" : "=r"(ui32Primask_04172010)); \ + __asm(" cpsid i"); + +#define AM_CRITICAL_END_ASM \ + __asm(" msr PRIMASK, %0" : : "r"(ui32Primask_04172010)); \ + } + +#elif defined(__ARMCC_VERSION) +// +// ARM/Keil macros. +// +#define AM_CRITICAL_BEGIN_ASM \ + if ( 1 ) \ + { \ + volatile uint32_t ui32Primask_04172010; \ + __asm \ + { \ + mrs ui32Primask_04172010, PRIMASK; \ + cpsid i; \ + } + +#define AM_CRITICAL_END_ASM \ + __asm \ + { \ + msr PRIMASK, ui32Primask_04172010; \ + } \ + } + +#elif defined(__IAR_SYSTEMS_ICC__) +// +// IAR macros. +// +#define AM_CRITICAL_BEGIN_ASM \ + if ( 1 ) \ + { \ + volatile uint32_t ui32Primask_04172010; \ + __asm(" mrs %0, PRIMASK" : "=r"(ui32Primask_04172010)); \ + __asm(" cpsid i"); + +#define AM_CRITICAL_END_ASM \ + __asm(" msr PRIMASK, %0" : : "r"(ui32Primask_04172010)); \ + } +#endif + + +//***************************************************************************** +// +// A collection of some common inline assembly instructions / intrinsics. +// +//***************************************************************************** +// +// AM_ASM_BKPT(n) +// +#if defined(__ARMCC_VERSION) +#define AM_ASM_BKPT(n) __breakpoint(n) +#elif defined(__IAR_SYSTEMS_ICC__) +#define AM_ASM_BKPT(n) asm(" bkpt "#n); +#else +#define AM_ASM_BKPT(n) __asm(" bkpt "#n); +#endif + +// +// AM_ASM_WFI +// +#if defined(__ARMCC_VERSION) +#define AM_ASM_WFI __wfi(); +#elif defined(__IAR_SYSTEMS_ICC__) +#define AM_ASM_WFI asm(" wfi"); +#else +#define AM_ASM_WFI __asm(" wfi"); +#endif + +// +// AM_ASM_NOP +// +#if defined(__ARMCC_VERSION) +#define AM_ASM_NOP __nop(); +#elif defined(__IAR_SYSTEMS_ICC__) +#define AM_ASM_NOP asm(" nop"); +#else +#define AM_ASM_NOP __asm(" nop"); +#endif + +#ifdef __cplusplus +} +#endif + +#endif // AM_REG_MACROS_ASM_H + diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_mcuctrl.h b/bsp/apollo2/libraries/drivers/regs/am_reg_mcuctrl.h new file mode 100644 index 0000000000..ae066bf85d --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_mcuctrl.h @@ -0,0 +1,607 @@ +//***************************************************************************** +// +// am_reg_mcuctrl.h +//! @file +//! +//! @brief Register macros for the MCUCTRL module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_MCUCTRL_H +#define AM_REG_MCUCTRL_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_MCUCTRL_NUM_MODULES 1 +#define AM_REG_MCUCTRLn(n) \ + (REG_MCUCTRL_BASEADDR + 0x00000000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_MCUCTRL_CHIP_INFO_O 0x00000000 +#define AM_REG_MCUCTRL_CHIPID0_O 0x00000004 +#define AM_REG_MCUCTRL_CHIPID1_O 0x00000008 +#define AM_REG_MCUCTRL_CHIPREV_O 0x0000000C +#define AM_REG_MCUCTRL_VENDORID_O 0x00000010 +#define AM_REG_MCUCTRL_DEBUGGER_O 0x00000014 +#define AM_REG_MCUCTRL_BUCK_O 0x00000060 +#define AM_REG_MCUCTRL_BUCK3_O 0x00000068 +#define AM_REG_MCUCTRL_LDOREG1_O 0x00000080 +#define AM_REG_MCUCTRL_LDOREG3_O 0x00000088 +#define AM_REG_MCUCTRL_BODPORCTRL_O 0x00000100 +#define AM_REG_MCUCTRL_ADCPWRDLY_O 0x00000104 +#define AM_REG_MCUCTRL_ADCCAL_O 0x0000010C +#define AM_REG_MCUCTRL_ADCBATTLOAD_O 0x00000110 +#define AM_REG_MCUCTRL_BUCKTRIM_O 0x00000114 +#define AM_REG_MCUCTRL_BOOTLOADERLOW_O 0x000001A0 +#define AM_REG_MCUCTRL_SHADOWVALID_O 0x000001A4 +#define AM_REG_MCUCTRL_ICODEFAULTADDR_O 0x000001C0 +#define AM_REG_MCUCTRL_DCODEFAULTADDR_O 0x000001C4 +#define AM_REG_MCUCTRL_SYSFAULTADDR_O 0x000001C8 +#define AM_REG_MCUCTRL_FAULTSTATUS_O 0x000001CC +#define AM_REG_MCUCTRL_FAULTCAPTUREEN_O 0x000001D0 +#define AM_REG_MCUCTRL_DBGR1_O 0x00000200 +#define AM_REG_MCUCTRL_DBGR2_O 0x00000204 +#define AM_REG_MCUCTRL_PMUENABLE_O 0x00000220 +#define AM_REG_MCUCTRL_TPIUCTRL_O 0x00000250 + +//***************************************************************************** +// +// Key values. +// +//***************************************************************************** + +//***************************************************************************** +// +// MCUCTRL_CHIP_INFO - Chip Information Register +// +//***************************************************************************** +// BCD part number. +#define AM_REG_MCUCTRL_CHIP_INFO_PARTNUM_S 0 +#define AM_REG_MCUCTRL_CHIP_INFO_PARTNUM_M 0xFFFFFFFF +#define AM_REG_MCUCTRL_CHIP_INFO_PARTNUM(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) +#define AM_REG_MCUCTRL_CHIP_INFO_PARTNUM_APOLLO2 0x03000000 +#define AM_REG_MCUCTRL_CHIP_INFO_PARTNUM_APOLLO 0x01000000 +#define AM_REG_MCUCTRL_CHIP_INFO_PARTNUM_PN_M 0xFF000000 + +//***************************************************************************** +// +// MCUCTRL_CHIPID0 - Unique Chip ID 0 +// +//***************************************************************************** +// Unique chip ID 0. +#define AM_REG_MCUCTRL_CHIPID0_VALUE_S 0 +#define AM_REG_MCUCTRL_CHIPID0_VALUE_M 0xFFFFFFFF +#define AM_REG_MCUCTRL_CHIPID0_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) +#define AM_REG_MCUCTRL_CHIPID0_VALUE_APOLLO2 0x00000000 + +//***************************************************************************** +// +// MCUCTRL_CHIPID1 - Unique Chip ID 1 +// +//***************************************************************************** +// Unique chip ID 1. +#define AM_REG_MCUCTRL_CHIPID1_VALUE_S 0 +#define AM_REG_MCUCTRL_CHIPID1_VALUE_M 0xFFFFFFFF +#define AM_REG_MCUCTRL_CHIPID1_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) +#define AM_REG_MCUCTRL_CHIPID1_VALUE_APOLLO2 0x00000000 + +//***************************************************************************** +// +// MCUCTRL_CHIPREV - Chip Revision +// +//***************************************************************************** +// Major Revision ID. +#define AM_REG_MCUCTRL_CHIPREV_REVMAJ_S 4 +#define AM_REG_MCUCTRL_CHIPREV_REVMAJ_M 0x000000F0 +#define AM_REG_MCUCTRL_CHIPREV_REVMAJ(n) (((uint32_t)(n) << 4) & 0x000000F0) +#define AM_REG_MCUCTRL_CHIPREV_REVMAJ_B 0x00000020 +#define AM_REG_MCUCTRL_CHIPREV_REVMAJ_A 0x00000010 + +// Minor Revision ID. +#define AM_REG_MCUCTRL_CHIPREV_REVMIN_S 0 +#define AM_REG_MCUCTRL_CHIPREV_REVMIN_M 0x0000000F +#define AM_REG_MCUCTRL_CHIPREV_REVMIN(n) (((uint32_t)(n) << 0) & 0x0000000F) +#define AM_REG_MCUCTRL_CHIPREV_REVMIN_REV0 0x00000000 + +//***************************************************************************** +// +// MCUCTRL_VENDORID - Unique Vendor ID +// +//***************************************************************************** +// Unique Vendor ID +#define AM_REG_MCUCTRL_VENDORID_VALUE_S 0 +#define AM_REG_MCUCTRL_VENDORID_VALUE_M 0xFFFFFFFF +#define AM_REG_MCUCTRL_VENDORID_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) +#define AM_REG_MCUCTRL_VENDORID_VALUE_AMBIQ 0x414D4251 + +//***************************************************************************** +// +// MCUCTRL_DEBUGGER - Debugger Access Control +// +//***************************************************************************** +// Lockout of debugger (SWD). +#define AM_REG_MCUCTRL_DEBUGGER_LOCKOUT_S 0 +#define AM_REG_MCUCTRL_DEBUGGER_LOCKOUT_M 0x00000001 +#define AM_REG_MCUCTRL_DEBUGGER_LOCKOUT(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// MCUCTRL_BUCK - Analog Buck Control +// +//***************************************************************************** +// Reset control override for Mem Buck; 0=enabled, 1=reset; Value is propagated +// only when the BUCKSWE bit is active, otherwise contrl is from the power +// control module. +#define AM_REG_MCUCTRL_BUCK_MEMBUCKRST_S 7 +#define AM_REG_MCUCTRL_BUCK_MEMBUCKRST_M 0x00000080 +#define AM_REG_MCUCTRL_BUCK_MEMBUCKRST(n) (((uint32_t)(n) << 7) & 0x00000080) + +// Reset control override for Core Buck; 0=enabled, 1=reset; Value is propagated +// only when the BUCKSWE bit is active, otherwise control is from the power +// control module. +#define AM_REG_MCUCTRL_BUCK_COREBUCKRST_S 6 +#define AM_REG_MCUCTRL_BUCK_COREBUCKRST_M 0x00000040 +#define AM_REG_MCUCTRL_BUCK_COREBUCKRST(n) (((uint32_t)(n) << 6) & 0x00000040) + +// Not used. Additional control of buck is available in the power control +// module +#define AM_REG_MCUCTRL_BUCK_BYPBUCKMEM_S 5 +#define AM_REG_MCUCTRL_BUCK_BYPBUCKMEM_M 0x00000020 +#define AM_REG_MCUCTRL_BUCK_BYPBUCKMEM(n) (((uint32_t)(n) << 5) & 0x00000020) + +// Memory buck power down override. 1=Powered Down; 0=Enabled; Value is +// propagated only when the BUCKSWE bit is active, otherwise control is from the +// power control module. +#define AM_REG_MCUCTRL_BUCK_MEMBUCKPWD_S 4 +#define AM_REG_MCUCTRL_BUCK_MEMBUCKPWD_M 0x00000010 +#define AM_REG_MCUCTRL_BUCK_MEMBUCKPWD(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_MCUCTRL_BUCK_MEMBUCKPWD_EN 0x00000000 + +// HFRC clkgen bit 0 override. When set, this will override to 0 bit 0 of the +// hfrc_freq_clkgen internal bus (see internal Shelby-1473) +#define AM_REG_MCUCTRL_BUCK_SLEEPBUCKANA_S 3 +#define AM_REG_MCUCTRL_BUCK_SLEEPBUCKANA_M 0x00000008 +#define AM_REG_MCUCTRL_BUCK_SLEEPBUCKANA(n) (((uint32_t)(n) << 3) & 0x00000008) + +// Core buck power down override. 1=Powered Down; 0=Enabled; Value is propagated +// only when the BUCKSWE bit is active, otherwise control is from the power +// control module. +#define AM_REG_MCUCTRL_BUCK_COREBUCKPWD_S 2 +#define AM_REG_MCUCTRL_BUCK_COREBUCKPWD_M 0x00000004 +#define AM_REG_MCUCTRL_BUCK_COREBUCKPWD(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_MCUCTRL_BUCK_COREBUCKPWD_EN 0x00000000 + +// Not used. Additional control of buck is available in the power control +// module +#define AM_REG_MCUCTRL_BUCK_BYPBUCKCORE_S 1 +#define AM_REG_MCUCTRL_BUCK_BYPBUCKCORE_M 0x00000002 +#define AM_REG_MCUCTRL_BUCK_BYPBUCKCORE(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Buck Register Software Override Enable. This will enable the override values +// for MEMBUCKPWD, COREBUCKPWD, COREBUCKRST, MEMBUCKRST, all to be propagated to +// the control logic, instead of the normal power control module signal. Note - +// Must take care to have correct value for ALL the register bits when this SWE +// is enabled. +#define AM_REG_MCUCTRL_BUCK_BUCKSWE_S 0 +#define AM_REG_MCUCTRL_BUCK_BUCKSWE_M 0x00000001 +#define AM_REG_MCUCTRL_BUCK_BUCKSWE(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_MCUCTRL_BUCK_BUCKSWE_OVERRIDE_DIS 0x00000000 +#define AM_REG_MCUCTRL_BUCK_BUCKSWE_OVERRIDE_EN 0x00000001 + +//***************************************************************************** +// +// MCUCTRL_BUCK3 - Buck control reg 3 +// +//***************************************************************************** +// MEM Buck low TON trim value +#define AM_REG_MCUCTRL_BUCK3_MEMBUCKLOTON_S 18 +#define AM_REG_MCUCTRL_BUCK3_MEMBUCKLOTON_M 0x003C0000 +#define AM_REG_MCUCTRL_BUCK3_MEMBUCKLOTON(n) (((uint32_t)(n) << 18) & 0x003C0000) + +// MEM Buck burst enable 0=disable, 0=disabled, 1=enable. +#define AM_REG_MCUCTRL_BUCK3_MEMBUCKBURSTEN_S 17 +#define AM_REG_MCUCTRL_BUCK3_MEMBUCKBURSTEN_M 0x00020000 +#define AM_REG_MCUCTRL_BUCK3_MEMBUCKBURSTEN(n) (((uint32_t)(n) << 17) & 0x00020000) + +// Memory buck zero crossing trim value +#define AM_REG_MCUCTRL_BUCK3_MEMBUCKZXTRIM_S 13 +#define AM_REG_MCUCTRL_BUCK3_MEMBUCKZXTRIM_M 0x0001E000 +#define AM_REG_MCUCTRL_BUCK3_MEMBUCKZXTRIM(n) (((uint32_t)(n) << 13) & 0x0001E000) + +// Hysterisis trim for mem buck +#define AM_REG_MCUCTRL_BUCK3_MEMBUCKHYSTTRIM_S 11 +#define AM_REG_MCUCTRL_BUCK3_MEMBUCKHYSTTRIM_M 0x00001800 +#define AM_REG_MCUCTRL_BUCK3_MEMBUCKHYSTTRIM(n) (((uint32_t)(n) << 11) & 0x00001800) + +// Core Buck low TON trim value +#define AM_REG_MCUCTRL_BUCK3_COREBUCKLOTON_S 7 +#define AM_REG_MCUCTRL_BUCK3_COREBUCKLOTON_M 0x00000780 +#define AM_REG_MCUCTRL_BUCK3_COREBUCKLOTON(n) (((uint32_t)(n) << 7) & 0x00000780) + +// Core Buck burst enable. 0=disabled, 1=enabled +#define AM_REG_MCUCTRL_BUCK3_COREBUCKBURSTEN_S 6 +#define AM_REG_MCUCTRL_BUCK3_COREBUCKBURSTEN_M 0x00000040 +#define AM_REG_MCUCTRL_BUCK3_COREBUCKBURSTEN(n) (((uint32_t)(n) << 6) & 0x00000040) + +// Core buck zero crossing trim value +#define AM_REG_MCUCTRL_BUCK3_COREBUCKZXTRIM_S 2 +#define AM_REG_MCUCTRL_BUCK3_COREBUCKZXTRIM_M 0x0000003C +#define AM_REG_MCUCTRL_BUCK3_COREBUCKZXTRIM(n) (((uint32_t)(n) << 2) & 0x0000003C) + +// Hysterisis trim for core buck +#define AM_REG_MCUCTRL_BUCK3_COREBUCKHYSTTRIM_S 0 +#define AM_REG_MCUCTRL_BUCK3_COREBUCKHYSTTRIM_M 0x00000003 +#define AM_REG_MCUCTRL_BUCK3_COREBUCKHYSTTRIM(n) (((uint32_t)(n) << 0) & 0x00000003) + +//***************************************************************************** +// +// MCUCTRL_LDOREG1 - Analog LDO Reg 1 +// +//***************************************************************************** +// CORE LDO IBIAS Trim +#define AM_REG_MCUCTRL_LDOREG1_CORELDOIBSTRM_S 20 +#define AM_REG_MCUCTRL_LDOREG1_CORELDOIBSTRM_M 0x00100000 +#define AM_REG_MCUCTRL_LDOREG1_CORELDOIBSTRM(n) (((uint32_t)(n) << 20) & 0x00100000) + +// CORE LDO Low Power Trim +#define AM_REG_MCUCTRL_LDOREG1_CORELDOLPTRIM_S 14 +#define AM_REG_MCUCTRL_LDOREG1_CORELDOLPTRIM_M 0x000FC000 +#define AM_REG_MCUCTRL_LDOREG1_CORELDOLPTRIM(n) (((uint32_t)(n) << 14) & 0x000FC000) + +// CORE LDO tempco trim (R3). +#define AM_REG_MCUCTRL_LDOREG1_TRIMCORELDOR3_S 10 +#define AM_REG_MCUCTRL_LDOREG1_TRIMCORELDOR3_M 0x00003C00 +#define AM_REG_MCUCTRL_LDOREG1_TRIMCORELDOR3(n) (((uint32_t)(n) << 10) & 0x00003C00) + +// CORE LDO Active mode ouput trim (R1). +#define AM_REG_MCUCTRL_LDOREG1_TRIMCORELDOR1_S 0 +#define AM_REG_MCUCTRL_LDOREG1_TRIMCORELDOR1_M 0x000003FF +#define AM_REG_MCUCTRL_LDOREG1_TRIMCORELDOR1(n) (((uint32_t)(n) << 0) & 0x000003FF) + +//***************************************************************************** +// +// MCUCTRL_LDOREG3 - LDO Control Register 3 +// +//***************************************************************************** +// MEM LDO active mode trim (R1). +#define AM_REG_MCUCTRL_LDOREG3_TRIMMEMLDOR1_S 12 +#define AM_REG_MCUCTRL_LDOREG3_TRIMMEMLDOR1_M 0x0003F000 +#define AM_REG_MCUCTRL_LDOREG3_TRIMMEMLDOR1(n) (((uint32_t)(n) << 12) & 0x0003F000) + +// MEM LDO TRIM for low power mode with ADC active +#define AM_REG_MCUCTRL_LDOREG3_MEMLDOLPALTTRIM_S 6 +#define AM_REG_MCUCTRL_LDOREG3_MEMLDOLPALTTRIM_M 0x00000FC0 +#define AM_REG_MCUCTRL_LDOREG3_MEMLDOLPALTTRIM(n) (((uint32_t)(n) << 6) & 0x00000FC0) + +// MEM LDO TRIM for low power mode with ADC inactive +#define AM_REG_MCUCTRL_LDOREG3_MEMLDOLPTRIM_S 0 +#define AM_REG_MCUCTRL_LDOREG3_MEMLDOLPTRIM_M 0x0000003F +#define AM_REG_MCUCTRL_LDOREG3_MEMLDOLPTRIM(n) (((uint32_t)(n) << 0) & 0x0000003F) + +//***************************************************************************** +// +// MCUCTRL_BODPORCTRL - BOD and PDR control Register +// +//***************************************************************************** +// BOD External Reference Select. +#define AM_REG_MCUCTRL_BODPORCTRL_BODEXTREFSEL_S 3 +#define AM_REG_MCUCTRL_BODPORCTRL_BODEXTREFSEL_M 0x00000008 +#define AM_REG_MCUCTRL_BODPORCTRL_BODEXTREFSEL(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_MCUCTRL_BODPORCTRL_BODEXTREFSEL_SELECT 0x00000008 + +// PDR External Reference Select. +#define AM_REG_MCUCTRL_BODPORCTRL_PDREXTREFSEL_S 2 +#define AM_REG_MCUCTRL_BODPORCTRL_PDREXTREFSEL_M 0x00000004 +#define AM_REG_MCUCTRL_BODPORCTRL_PDREXTREFSEL(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_MCUCTRL_BODPORCTRL_PDREXTREFSEL_SELECT 0x00000004 + +// BOD Power Down. +#define AM_REG_MCUCTRL_BODPORCTRL_PWDBOD_S 1 +#define AM_REG_MCUCTRL_BODPORCTRL_PWDBOD_M 0x00000002 +#define AM_REG_MCUCTRL_BODPORCTRL_PWDBOD(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_MCUCTRL_BODPORCTRL_PWDBOD_PWR_DN 0x00000002 + +// PDR Power Down. +#define AM_REG_MCUCTRL_BODPORCTRL_PWDPDR_S 0 +#define AM_REG_MCUCTRL_BODPORCTRL_PWDPDR_M 0x00000001 +#define AM_REG_MCUCTRL_BODPORCTRL_PWDPDR(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_MCUCTRL_BODPORCTRL_PWDPDR_PWR_DN 0x00000001 + +//***************************************************************************** +// +// MCUCTRL_ADCPWRDLY - ADC Power Up Delay Control +// +//***************************************************************************** +// ADC Reference Keeper enable delay in 16 ADC CLK increments for ADC_CLKSEL = +// 0x1, 8 ADC CLOCK increments for ADC_CLKSEL = 0x2. +#define AM_REG_MCUCTRL_ADCPWRDLY_ADCPWR1_S 8 +#define AM_REG_MCUCTRL_ADCPWRDLY_ADCPWR1_M 0x0000FF00 +#define AM_REG_MCUCTRL_ADCPWRDLY_ADCPWR1(n) (((uint32_t)(n) << 8) & 0x0000FF00) + +// ADC Reference Buffer Power Enable delay in 64 ADC CLK increments for +// ADC_CLKSEL = 0x1, 32 ADC CLOCK increments for ADC_CLKSEL = 0x2. +#define AM_REG_MCUCTRL_ADCPWRDLY_ADCPWR0_S 0 +#define AM_REG_MCUCTRL_ADCPWRDLY_ADCPWR0_M 0x000000FF +#define AM_REG_MCUCTRL_ADCPWRDLY_ADCPWR0(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// MCUCTRL_ADCCAL - ADC Calibration Control +// +//***************************************************************************** +// Status for ADC Calibration +#define AM_REG_MCUCTRL_ADCCAL_ADCCALIBRATED_S 1 +#define AM_REG_MCUCTRL_ADCCAL_ADCCALIBRATED_M 0x00000002 +#define AM_REG_MCUCTRL_ADCCAL_ADCCALIBRATED(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_MCUCTRL_ADCCAL_ADCCALIBRATED_FALSE 0x00000000 +#define AM_REG_MCUCTRL_ADCCAL_ADCCALIBRATED_TRUE 0x00000002 + +// Run ADC Calibration on initial power up sequence +#define AM_REG_MCUCTRL_ADCCAL_CALONPWRUP_S 0 +#define AM_REG_MCUCTRL_ADCCAL_CALONPWRUP_M 0x00000001 +#define AM_REG_MCUCTRL_ADCCAL_CALONPWRUP(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_MCUCTRL_ADCCAL_CALONPWRUP_DIS 0x00000000 +#define AM_REG_MCUCTRL_ADCCAL_CALONPWRUP_EN 0x00000001 + +//***************************************************************************** +// +// MCUCTRL_ADCBATTLOAD - ADC Battery Load Enable +// +//***************************************************************************** +// Enable the ADC battery load resistor +#define AM_REG_MCUCTRL_ADCBATTLOAD_BATTLOAD_S 0 +#define AM_REG_MCUCTRL_ADCBATTLOAD_BATTLOAD_M 0x00000001 +#define AM_REG_MCUCTRL_ADCBATTLOAD_BATTLOAD(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_MCUCTRL_ADCBATTLOAD_BATTLOAD_DIS 0x00000000 +#define AM_REG_MCUCTRL_ADCBATTLOAD_BATTLOAD_EN 0x00000001 + +//***************************************************************************** +// +// MCUCTRL_BUCKTRIM - Trim settings for Core and Mem buck modules +// +//***************************************************************************** +// RESERVED. +#define AM_REG_MCUCTRL_BUCKTRIM_RSVD2_S 24 +#define AM_REG_MCUCTRL_BUCKTRIM_RSVD2_M 0x3F000000 +#define AM_REG_MCUCTRL_BUCKTRIM_RSVD2(n) (((uint32_t)(n) << 24) & 0x3F000000) + +// Core Buck voltage output trim bits[9:6]. Concatenate with field COREBUCKR1_LO +// for the full trim value. +#define AM_REG_MCUCTRL_BUCKTRIM_COREBUCKR1_HI_S 16 +#define AM_REG_MCUCTRL_BUCKTRIM_COREBUCKR1_HI_M 0x000F0000 +#define AM_REG_MCUCTRL_BUCKTRIM_COREBUCKR1_HI(n) (((uint32_t)(n) << 16) & 0x000F0000) + +// Core Buck voltage output trim bits[5:0], Concatenate with field COREBUCKR1_HI +// for the full trim value. +#define AM_REG_MCUCTRL_BUCKTRIM_COREBUCKR1_LO_S 8 +#define AM_REG_MCUCTRL_BUCKTRIM_COREBUCKR1_LO_M 0x00003F00 +#define AM_REG_MCUCTRL_BUCKTRIM_COREBUCKR1_LO(n) (((uint32_t)(n) << 8) & 0x00003F00) + +// Trim values for BUCK regulator. +#define AM_REG_MCUCTRL_BUCKTRIM_MEMBUCKR1_S 0 +#define AM_REG_MCUCTRL_BUCKTRIM_MEMBUCKR1_M 0x0000003F +#define AM_REG_MCUCTRL_BUCKTRIM_MEMBUCKR1(n) (((uint32_t)(n) << 0) & 0x0000003F) + +//***************************************************************************** +// +// MCUCTRL_BOOTLOADERLOW - Determines whether the bootloader code is visible at +// address 0x00000000 +// +//***************************************************************************** +// Determines whether the bootloader code is visible at address 0x00000000 or +// not. +#define AM_REG_MCUCTRL_BOOTLOADERLOW_VALUE_S 0 +#define AM_REG_MCUCTRL_BOOTLOADERLOW_VALUE_M 0x00000001 +#define AM_REG_MCUCTRL_BOOTLOADERLOW_VALUE(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_MCUCTRL_BOOTLOADERLOW_VALUE_ADDR0 0x00000001 + +//***************************************************************************** +// +// MCUCTRL_SHADOWVALID - Register to indicate whether the shadow registers have +// been successfully loaded from the Flash Information Space. +// +//***************************************************************************** +// Indicates whether the bootloader should sleep or deep sleep if no image +// loaded. +#define AM_REG_MCUCTRL_SHADOWVALID_BL_DSLEEP_S 1 +#define AM_REG_MCUCTRL_SHADOWVALID_BL_DSLEEP_M 0x00000002 +#define AM_REG_MCUCTRL_SHADOWVALID_BL_DSLEEP(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_MCUCTRL_SHADOWVALID_BL_DSLEEP_DEEPSLEEP 0x00000002 + +// Indicates whether the shadow registers contain valid data from the Flash +// Information Space. +#define AM_REG_MCUCTRL_SHADOWVALID_VALID_S 0 +#define AM_REG_MCUCTRL_SHADOWVALID_VALID_M 0x00000001 +#define AM_REG_MCUCTRL_SHADOWVALID_VALID(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_MCUCTRL_SHADOWVALID_VALID_VALID 0x00000001 + +//***************************************************************************** +// +// MCUCTRL_ICODEFAULTADDR - ICODE bus address which was present when a bus fault +// occurred. +// +//***************************************************************************** +// The ICODE bus address observed when a Bus Fault occurred. Once an address is +// captured in this field, it is held until the corresponding Fault Observed bit +// is cleared in the FAULTSTATUS register. +#define AM_REG_MCUCTRL_ICODEFAULTADDR_ADDR_S 0 +#define AM_REG_MCUCTRL_ICODEFAULTADDR_ADDR_M 0xFFFFFFFF +#define AM_REG_MCUCTRL_ICODEFAULTADDR_ADDR(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// MCUCTRL_DCODEFAULTADDR - DCODE bus address which was present when a bus fault +// occurred. +// +//***************************************************************************** +// The DCODE bus address observed when a Bus Fault occurred. Once an address is +// captured in this field, it is held until the corresponding Fault Observed bit +// is cleared in the FAULTSTATUS register. +#define AM_REG_MCUCTRL_DCODEFAULTADDR_ADDR_S 0 +#define AM_REG_MCUCTRL_DCODEFAULTADDR_ADDR_M 0xFFFFFFFF +#define AM_REG_MCUCTRL_DCODEFAULTADDR_ADDR(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// MCUCTRL_SYSFAULTADDR - System bus address which was present when a bus fault +// occurred. +// +//***************************************************************************** +// SYS bus address observed when a Bus Fault occurred. Once an address is +// captured in this field, it is held until the corresponding Fault Observed bit +// is cleared in the FAULTSTATUS register. +#define AM_REG_MCUCTRL_SYSFAULTADDR_ADDR_S 0 +#define AM_REG_MCUCTRL_SYSFAULTADDR_ADDR_M 0xFFFFFFFF +#define AM_REG_MCUCTRL_SYSFAULTADDR_ADDR(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// MCUCTRL_FAULTSTATUS - Reflects the status of the bus decoders' fault +// detection. Any write to this register will clear all of the status bits +// within the register. +// +//***************************************************************************** +// SYS Bus Decoder Fault Detected bit. When set, a fault has been detected, and +// the SYSFAULTADDR register will contain the bus address which generated the +// fault. +#define AM_REG_MCUCTRL_FAULTSTATUS_SYS_S 2 +#define AM_REG_MCUCTRL_FAULTSTATUS_SYS_M 0x00000004 +#define AM_REG_MCUCTRL_FAULTSTATUS_SYS(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_MCUCTRL_FAULTSTATUS_SYS_NOFAULT 0x00000000 +#define AM_REG_MCUCTRL_FAULTSTATUS_SYS_FAULT 0x00000004 + +// DCODE Bus Decoder Fault Detected bit. When set, a fault has been detected, +// and the DCODEFAULTADDR register will contain the bus address which generated +// the fault. +#define AM_REG_MCUCTRL_FAULTSTATUS_DCODE_S 1 +#define AM_REG_MCUCTRL_FAULTSTATUS_DCODE_M 0x00000002 +#define AM_REG_MCUCTRL_FAULTSTATUS_DCODE(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_MCUCTRL_FAULTSTATUS_DCODE_NOFAULT 0x00000000 +#define AM_REG_MCUCTRL_FAULTSTATUS_DCODE_FAULT 0x00000002 + +// The ICODE Bus Decoder Fault Detected bit. When set, a fault has been +// detected, and the ICODEFAULTADDR register will contain the bus address which +// generated the fault. +#define AM_REG_MCUCTRL_FAULTSTATUS_ICODE_S 0 +#define AM_REG_MCUCTRL_FAULTSTATUS_ICODE_M 0x00000001 +#define AM_REG_MCUCTRL_FAULTSTATUS_ICODE(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_MCUCTRL_FAULTSTATUS_ICODE_NOFAULT 0x00000000 +#define AM_REG_MCUCTRL_FAULTSTATUS_ICODE_FAULT 0x00000001 + +//***************************************************************************** +// +// MCUCTRL_FAULTCAPTUREEN - Enable the fault capture registers +// +//***************************************************************************** +// Fault Capture Enable field. When set, the Fault Capture monitors are enabled +// and addresses which generate a hard fault are captured into the FAULTADDR +// registers. +#define AM_REG_MCUCTRL_FAULTCAPTUREEN_ENABLE_S 0 +#define AM_REG_MCUCTRL_FAULTCAPTUREEN_ENABLE_M 0x00000001 +#define AM_REG_MCUCTRL_FAULTCAPTUREEN_ENABLE(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_MCUCTRL_FAULTCAPTUREEN_ENABLE_DIS 0x00000000 +#define AM_REG_MCUCTRL_FAULTCAPTUREEN_ENABLE_EN 0x00000001 + +//***************************************************************************** +// +// MCUCTRL_DBGR1 - Read-only debug register 1 +// +//***************************************************************************** +// Read-only register for communication validation +#define AM_REG_MCUCTRL_DBGR1_ONETO8_S 0 +#define AM_REG_MCUCTRL_DBGR1_ONETO8_M 0xFFFFFFFF +#define AM_REG_MCUCTRL_DBGR1_ONETO8(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// MCUCTRL_DBGR2 - Read-only debug register 2 +// +//***************************************************************************** +// Read-only register for communication validation +#define AM_REG_MCUCTRL_DBGR2_COOLCODE_S 0 +#define AM_REG_MCUCTRL_DBGR2_COOLCODE_M 0xFFFFFFFF +#define AM_REG_MCUCTRL_DBGR2_COOLCODE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// MCUCTRL_PMUENABLE - Control bit to enable/disable the PMU +// +//***************************************************************************** +// PMU Enable Control bit. When set, the MCU's PMU will place the MCU into the +// lowest power consuming Deep Sleep mode upon execution of a WFI instruction +// (dependent on the setting of the SLEEPDEEP bit in the ARM SCR register). When +// cleared, regardless of the requested sleep mode, the PMU will not enter the +// lowest power Deep Sleep mode, instead entering the Sleep mode. +#define AM_REG_MCUCTRL_PMUENABLE_ENABLE_S 0 +#define AM_REG_MCUCTRL_PMUENABLE_ENABLE_M 0x00000001 +#define AM_REG_MCUCTRL_PMUENABLE_ENABLE(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_MCUCTRL_PMUENABLE_ENABLE_DIS 0x00000000 +#define AM_REG_MCUCTRL_PMUENABLE_ENABLE_EN 0x00000001 + +//***************************************************************************** +// +// MCUCTRL_TPIUCTRL - TPIU Control Register. Determines the clock enable and +// frequency for the M4's TPIU interface. +// +//***************************************************************************** +// This field selects the frequency of the ARM M4 TPIU port. +#define AM_REG_MCUCTRL_TPIUCTRL_CLKSEL_S 8 +#define AM_REG_MCUCTRL_TPIUCTRL_CLKSEL_M 0x00000700 +#define AM_REG_MCUCTRL_TPIUCTRL_CLKSEL(n) (((uint32_t)(n) << 8) & 0x00000700) +#define AM_REG_MCUCTRL_TPIUCTRL_CLKSEL_LOW_PWR 0x00000000 +#define AM_REG_MCUCTRL_TPIUCTRL_CLKSEL_0MHz 0x00000000 +#define AM_REG_MCUCTRL_TPIUCTRL_CLKSEL_HFRC_DIV_2 0x00000100 +#define AM_REG_MCUCTRL_TPIUCTRL_CLKSEL_HFRC_DIV_8 0x00000200 +#define AM_REG_MCUCTRL_TPIUCTRL_CLKSEL_HFRC_DIV_16 0x00000300 +#define AM_REG_MCUCTRL_TPIUCTRL_CLKSEL_HFRC_DIV_32 0x00000400 + +// TPIU Enable field. When set, the ARM M4 TPIU is enabled and data can be +// streamed out of the MCU's SWO port using the ARM ITM and TPIU modules. +#define AM_REG_MCUCTRL_TPIUCTRL_ENABLE_S 0 +#define AM_REG_MCUCTRL_TPIUCTRL_ENABLE_M 0x00000001 +#define AM_REG_MCUCTRL_TPIUCTRL_ENABLE(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_MCUCTRL_TPIUCTRL_ENABLE_DIS 0x00000000 +#define AM_REG_MCUCTRL_TPIUCTRL_ENABLE_EN 0x00000001 + +#endif // AM_REG_MCUCTRL_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_nvic.h b/bsp/apollo2/libraries/drivers/regs/am_reg_nvic.h new file mode 100644 index 0000000000..349991e28f --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_nvic.h @@ -0,0 +1,325 @@ +//***************************************************************************** +// +// am_reg_nvic.h +//! @file +//! +//! @brief Register macros for the NVIC module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_NVIC_H +#define AM_REG_NVIC_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_NVIC_NUM_MODULES 1 +#define AM_REG_NVICn(n) \ + (REG_NVIC_BASEADDR + 0x00000000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_NVIC_ISER0_O 0xE000E100 +#define AM_REG_NVIC_ICER0_O 0xE000E180 +#define AM_REG_NVIC_ISPR0_O 0xE000E200 +#define AM_REG_NVIC_ICPR0_O 0xE000E280 +#define AM_REG_NVIC_IABR0_O 0xE000E300 +#define AM_REG_NVIC_IPR0_O 0xE000E400 +#define AM_REG_NVIC_IPR1_O 0xE000E404 +#define AM_REG_NVIC_IPR2_O 0xE000E408 +#define AM_REG_NVIC_IPR3_O 0xE000E40C +#define AM_REG_NVIC_IPR4_O 0xE000E410 +#define AM_REG_NVIC_IPR5_O 0xE000E414 +#define AM_REG_NVIC_IPR6_O 0xE000E418 +#define AM_REG_NVIC_IPR7_O 0xE000E41C + +//***************************************************************************** +// +// NVIC_ISER0 - Interrupt Set-Enable Register 0 +// +//***************************************************************************** +// NVIC_ISERn[31:0] are the set-enable bits for interrupts 31 through 0. +#define AM_REG_NVIC_ISER0_BITS_S 0 +#define AM_REG_NVIC_ISER0_BITS_M 0xFFFFFFFF +#define AM_REG_NVIC_ISER0_BITS(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// NVIC_ICER0 - Interrupt Clear-Enable Register 0 +// +//***************************************************************************** +// NVIC_ISERn[31:0] are the clear-enable bits for interrupts 31 through 0. +#define AM_REG_NVIC_ICER0_BITS_S 0 +#define AM_REG_NVIC_ICER0_BITS_M 0xFFFFFFFF +#define AM_REG_NVIC_ICER0_BITS(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// NVIC_ISPR0 - Interrupt Set-Pending Register 0 +// +//***************************************************************************** +// NVIC_ISERn[31:0] are the set-pending bits for interrupts 31 through 0. +#define AM_REG_NVIC_ISPR0_BITS_S 0 +#define AM_REG_NVIC_ISPR0_BITS_M 0xFFFFFFFF +#define AM_REG_NVIC_ISPR0_BITS(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// NVIC_ICPR0 - Interrupt Clear-Pending Register 0 +// +//***************************************************************************** +// NVIC_ISERn[31:0] are the clear-pending bits for interrupts 31 through 0. +#define AM_REG_NVIC_ICPR0_BITS_S 0 +#define AM_REG_NVIC_ICPR0_BITS_M 0xFFFFFFFF +#define AM_REG_NVIC_ICPR0_BITS(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// NVIC_IABR0 - Interrupt Active Bit Register 0 +// +//***************************************************************************** +// NVIC_ISERn[31:0] are the interrupt active bits for interrupts 31 through 0. +#define AM_REG_NVIC_IABR0_BITS_S 0 +#define AM_REG_NVIC_IABR0_BITS_M 0xFFFFFFFF +#define AM_REG_NVIC_IABR0_BITS(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// NVIC_IPR0 - Interrupt Priority Register 0 +// +//***************************************************************************** +// Priority assignment for interrupt vector 3. +#define AM_REG_NVIC_IPR0_PRI_N3_S 24 +#define AM_REG_NVIC_IPR0_PRI_N3_M 0xFF000000 +#define AM_REG_NVIC_IPR0_PRI_N3(n) (((uint32_t)(n) << 24) & 0xFF000000) + +// Priority assignment for interrupt vector 2. +#define AM_REG_NVIC_IPR0_PRI_N2_S 16 +#define AM_REG_NVIC_IPR0_PRI_N2_M 0x00FF0000 +#define AM_REG_NVIC_IPR0_PRI_N2(n) (((uint32_t)(n) << 16) & 0x00FF0000) + +// Priority assignment for interrupt vector 1. +#define AM_REG_NVIC_IPR0_PRI_N1_S 8 +#define AM_REG_NVIC_IPR0_PRI_N1_M 0x0000FF00 +#define AM_REG_NVIC_IPR0_PRI_N1(n) (((uint32_t)(n) << 8) & 0x0000FF00) + +// Priority assignment for interrupt vector 0. +#define AM_REG_NVIC_IPR0_PRI_N0_S 0 +#define AM_REG_NVIC_IPR0_PRI_N0_M 0x000000FF +#define AM_REG_NVIC_IPR0_PRI_N0(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// NVIC_IPR1 - Interrupt Priority Register 1 +// +//***************************************************************************** +// Priority assignment for interrupt vector 7. +#define AM_REG_NVIC_IPR1_PRI_N3_S 24 +#define AM_REG_NVIC_IPR1_PRI_N3_M 0xFF000000 +#define AM_REG_NVIC_IPR1_PRI_N3(n) (((uint32_t)(n) << 24) & 0xFF000000) + +// Priority assignment for interrupt vector 6. +#define AM_REG_NVIC_IPR1_PRI_N2_S 16 +#define AM_REG_NVIC_IPR1_PRI_N2_M 0x00FF0000 +#define AM_REG_NVIC_IPR1_PRI_N2(n) (((uint32_t)(n) << 16) & 0x00FF0000) + +// Priority assignment for interrupt vector 5. +#define AM_REG_NVIC_IPR1_PRI_N1_S 8 +#define AM_REG_NVIC_IPR1_PRI_N1_M 0x0000FF00 +#define AM_REG_NVIC_IPR1_PRI_N1(n) (((uint32_t)(n) << 8) & 0x0000FF00) + +// Priority assignment for interrupt vector 4. +#define AM_REG_NVIC_IPR1_PRI_N0_S 0 +#define AM_REG_NVIC_IPR1_PRI_N0_M 0x000000FF +#define AM_REG_NVIC_IPR1_PRI_N0(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// NVIC_IPR2 - Interrupt Priority Register 2 +// +//***************************************************************************** +// Priority assignment for interrupt vector 11. +#define AM_REG_NVIC_IPR2_PRI_N3_S 24 +#define AM_REG_NVIC_IPR2_PRI_N3_M 0xFF000000 +#define AM_REG_NVIC_IPR2_PRI_N3(n) (((uint32_t)(n) << 24) & 0xFF000000) + +// Priority assignment for interrupt vector 10. +#define AM_REG_NVIC_IPR2_PRI_N2_S 16 +#define AM_REG_NVIC_IPR2_PRI_N2_M 0x00FF0000 +#define AM_REG_NVIC_IPR2_PRI_N2(n) (((uint32_t)(n) << 16) & 0x00FF0000) + +// Priority assignment for interrupt vector 9. +#define AM_REG_NVIC_IPR2_PRI_N1_S 8 +#define AM_REG_NVIC_IPR2_PRI_N1_M 0x0000FF00 +#define AM_REG_NVIC_IPR2_PRI_N1(n) (((uint32_t)(n) << 8) & 0x0000FF00) + +// Priority assignment for interrupt vector 8. +#define AM_REG_NVIC_IPR2_PRI_N0_S 0 +#define AM_REG_NVIC_IPR2_PRI_N0_M 0x000000FF +#define AM_REG_NVIC_IPR2_PRI_N0(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// NVIC_IPR3 - Interrupt Priority Register 3 +// +//***************************************************************************** +// Priority assignment for interrupt vector 15. +#define AM_REG_NVIC_IPR3_PRI_N3_S 24 +#define AM_REG_NVIC_IPR3_PRI_N3_M 0xFF000000 +#define AM_REG_NVIC_IPR3_PRI_N3(n) (((uint32_t)(n) << 24) & 0xFF000000) + +// Priority assignment for interrupt vector 14. +#define AM_REG_NVIC_IPR3_PRI_N2_S 16 +#define AM_REG_NVIC_IPR3_PRI_N2_M 0x00FF0000 +#define AM_REG_NVIC_IPR3_PRI_N2(n) (((uint32_t)(n) << 16) & 0x00FF0000) + +// Priority assignment for interrupt vector 13. +#define AM_REG_NVIC_IPR3_PRI_N1_S 8 +#define AM_REG_NVIC_IPR3_PRI_N1_M 0x0000FF00 +#define AM_REG_NVIC_IPR3_PRI_N1(n) (((uint32_t)(n) << 8) & 0x0000FF00) + +// Priority assignment for interrupt vector 12. +#define AM_REG_NVIC_IPR3_PRI_N0_S 0 +#define AM_REG_NVIC_IPR3_PRI_N0_M 0x000000FF +#define AM_REG_NVIC_IPR3_PRI_N0(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// NVIC_IPR4 - Interrupt Priority Register 4 +// +//***************************************************************************** +// Priority assignment for interrupt vector 19. +#define AM_REG_NVIC_IPR4_PRI_N3_S 24 +#define AM_REG_NVIC_IPR4_PRI_N3_M 0xFF000000 +#define AM_REG_NVIC_IPR4_PRI_N3(n) (((uint32_t)(n) << 24) & 0xFF000000) + +// Priority assignment for interrupt vector 18. +#define AM_REG_NVIC_IPR4_PRI_N2_S 16 +#define AM_REG_NVIC_IPR4_PRI_N2_M 0x00FF0000 +#define AM_REG_NVIC_IPR4_PRI_N2(n) (((uint32_t)(n) << 16) & 0x00FF0000) + +// Priority assignment for interrupt vector 17. +#define AM_REG_NVIC_IPR4_PRI_N1_S 8 +#define AM_REG_NVIC_IPR4_PRI_N1_M 0x0000FF00 +#define AM_REG_NVIC_IPR4_PRI_N1(n) (((uint32_t)(n) << 8) & 0x0000FF00) + +// Priority assignment for interrupt vector 16. +#define AM_REG_NVIC_IPR4_PRI_N0_S 0 +#define AM_REG_NVIC_IPR4_PRI_N0_M 0x000000FF +#define AM_REG_NVIC_IPR4_PRI_N0(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// NVIC_IPR5 - Interrupt Priority Register 5 +// +//***************************************************************************** +// Priority assignment for interrupt vector 23. +#define AM_REG_NVIC_IPR5_PRI_N3_S 24 +#define AM_REG_NVIC_IPR5_PRI_N3_M 0xFF000000 +#define AM_REG_NVIC_IPR5_PRI_N3(n) (((uint32_t)(n) << 24) & 0xFF000000) + +// Priority assignment for interrupt vector 22. +#define AM_REG_NVIC_IPR5_PRI_N2_S 16 +#define AM_REG_NVIC_IPR5_PRI_N2_M 0x00FF0000 +#define AM_REG_NVIC_IPR5_PRI_N2(n) (((uint32_t)(n) << 16) & 0x00FF0000) + +// Priority assignment for interrupt vector 21. +#define AM_REG_NVIC_IPR5_PRI_N1_S 8 +#define AM_REG_NVIC_IPR5_PRI_N1_M 0x0000FF00 +#define AM_REG_NVIC_IPR5_PRI_N1(n) (((uint32_t)(n) << 8) & 0x0000FF00) + +// Priority assignment for interrupt vector 20. +#define AM_REG_NVIC_IPR5_PRI_N0_S 0 +#define AM_REG_NVIC_IPR5_PRI_N0_M 0x000000FF +#define AM_REG_NVIC_IPR5_PRI_N0(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// NVIC_IPR6 - Interrupt Priority Register 6 +// +//***************************************************************************** +// Priority assignment for interrupt vector 27. +#define AM_REG_NVIC_IPR6_PRI_N3_S 24 +#define AM_REG_NVIC_IPR6_PRI_N3_M 0xFF000000 +#define AM_REG_NVIC_IPR6_PRI_N3(n) (((uint32_t)(n) << 24) & 0xFF000000) + +// Priority assignment for interrupt vector 26. +#define AM_REG_NVIC_IPR6_PRI_N2_S 16 +#define AM_REG_NVIC_IPR6_PRI_N2_M 0x00FF0000 +#define AM_REG_NVIC_IPR6_PRI_N2(n) (((uint32_t)(n) << 16) & 0x00FF0000) + +// Priority assignment for interrupt vector 25. +#define AM_REG_NVIC_IPR6_PRI_N1_S 8 +#define AM_REG_NVIC_IPR6_PRI_N1_M 0x0000FF00 +#define AM_REG_NVIC_IPR6_PRI_N1(n) (((uint32_t)(n) << 8) & 0x0000FF00) + +// Priority assignment for interrupt vector 24. +#define AM_REG_NVIC_IPR6_PRI_N0_S 0 +#define AM_REG_NVIC_IPR6_PRI_N0_M 0x000000FF +#define AM_REG_NVIC_IPR6_PRI_N0(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// NVIC_IPR7 - Interrupt Priority Register 7 +// +//***************************************************************************** +// Priority assignment for interrupt vector 31. +#define AM_REG_NVIC_IPR7_PRI_N3_S 24 +#define AM_REG_NVIC_IPR7_PRI_N3_M 0xFF000000 +#define AM_REG_NVIC_IPR7_PRI_N3(n) (((uint32_t)(n) << 24) & 0xFF000000) + +// Priority assignment for interrupt vector 30. +#define AM_REG_NVIC_IPR7_PRI_N2_S 16 +#define AM_REG_NVIC_IPR7_PRI_N2_M 0x00FF0000 +#define AM_REG_NVIC_IPR7_PRI_N2(n) (((uint32_t)(n) << 16) & 0x00FF0000) + +// Priority assignment for interrupt vector 29. +#define AM_REG_NVIC_IPR7_PRI_N1_S 8 +#define AM_REG_NVIC_IPR7_PRI_N1_M 0x0000FF00 +#define AM_REG_NVIC_IPR7_PRI_N1(n) (((uint32_t)(n) << 8) & 0x0000FF00) + +// Priority assignment for interrupt vector 28. +#define AM_REG_NVIC_IPR7_PRI_N0_S 0 +#define AM_REG_NVIC_IPR7_PRI_N0_M 0x000000FF +#define AM_REG_NVIC_IPR7_PRI_N0(n) (((uint32_t)(n) << 0) & 0x000000FF) + +#endif // AM_REG_NVIC_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_pdm.h b/bsp/apollo2/libraries/drivers/regs/am_reg_pdm.h new file mode 100644 index 0000000000..6a7c6aa3cf --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_pdm.h @@ -0,0 +1,374 @@ +//***************************************************************************** +// +// am_reg_pdm.h +//! @file +//! +//! @brief Register macros for the PDM module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_PDM_H +#define AM_REG_PDM_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_PDM_NUM_MODULES 1 +#define AM_REG_PDMn(n) \ + (REG_PDM_BASEADDR + 0x00000000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_PDM_PCFG_O 0x00000000 +#define AM_REG_PDM_VCFG_O 0x00000004 +#define AM_REG_PDM_FR_O 0x00000008 +#define AM_REG_PDM_FRD_O 0x0000000C +#define AM_REG_PDM_FLUSH_O 0x00000010 +#define AM_REG_PDM_FTHR_O 0x00000014 +#define AM_REG_PDM_INTEN_O 0x00000200 +#define AM_REG_PDM_INTSTAT_O 0x00000204 +#define AM_REG_PDM_INTCLR_O 0x00000208 +#define AM_REG_PDM_INTSET_O 0x0000020C + +//***************************************************************************** +// +// PDM_INTEN - IO Master Interrupts: Enable +// +//***************************************************************************** +// This is the FIFO underflow interrupt. +#define AM_REG_PDM_INTEN_UNDFL_S 2 +#define AM_REG_PDM_INTEN_UNDFL_M 0x00000004 +#define AM_REG_PDM_INTEN_UNDFL(n) (((uint32_t)(n) << 2) & 0x00000004) + +// This is the FIFO overflow interrupt. +#define AM_REG_PDM_INTEN_OVF_S 1 +#define AM_REG_PDM_INTEN_OVF_M 0x00000002 +#define AM_REG_PDM_INTEN_OVF(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This is the FIFO threshold interrupt. +#define AM_REG_PDM_INTEN_THR_S 0 +#define AM_REG_PDM_INTEN_THR_M 0x00000001 +#define AM_REG_PDM_INTEN_THR(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// PDM_INTSTAT - IO Master Interrupts: Status +// +//***************************************************************************** +// This is the FIFO underflow interrupt. +#define AM_REG_PDM_INTSTAT_UNDFL_S 2 +#define AM_REG_PDM_INTSTAT_UNDFL_M 0x00000004 +#define AM_REG_PDM_INTSTAT_UNDFL(n) (((uint32_t)(n) << 2) & 0x00000004) + +// This is the FIFO overflow interrupt. +#define AM_REG_PDM_INTSTAT_OVF_S 1 +#define AM_REG_PDM_INTSTAT_OVF_M 0x00000002 +#define AM_REG_PDM_INTSTAT_OVF(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This is the FIFO threshold interrupt. +#define AM_REG_PDM_INTSTAT_THR_S 0 +#define AM_REG_PDM_INTSTAT_THR_M 0x00000001 +#define AM_REG_PDM_INTSTAT_THR(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// PDM_INTCLR - IO Master Interrupts: Clear +// +//***************************************************************************** +// This is the FIFO underflow interrupt. +#define AM_REG_PDM_INTCLR_UNDFL_S 2 +#define AM_REG_PDM_INTCLR_UNDFL_M 0x00000004 +#define AM_REG_PDM_INTCLR_UNDFL(n) (((uint32_t)(n) << 2) & 0x00000004) + +// This is the FIFO overflow interrupt. +#define AM_REG_PDM_INTCLR_OVF_S 1 +#define AM_REG_PDM_INTCLR_OVF_M 0x00000002 +#define AM_REG_PDM_INTCLR_OVF(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This is the FIFO threshold interrupt. +#define AM_REG_PDM_INTCLR_THR_S 0 +#define AM_REG_PDM_INTCLR_THR_M 0x00000001 +#define AM_REG_PDM_INTCLR_THR(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// PDM_INTSET - IO Master Interrupts: Set +// +//***************************************************************************** +// This is the FIFO underflow interrupt. +#define AM_REG_PDM_INTSET_UNDFL_S 2 +#define AM_REG_PDM_INTSET_UNDFL_M 0x00000004 +#define AM_REG_PDM_INTSET_UNDFL(n) (((uint32_t)(n) << 2) & 0x00000004) + +// This is the FIFO overflow interrupt. +#define AM_REG_PDM_INTSET_OVF_S 1 +#define AM_REG_PDM_INTSET_OVF_M 0x00000002 +#define AM_REG_PDM_INTSET_OVF(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This is the FIFO threshold interrupt. +#define AM_REG_PDM_INTSET_THR_S 0 +#define AM_REG_PDM_INTSET_THR_M 0x00000001 +#define AM_REG_PDM_INTSET_THR(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// PDM_PCFG - PDM Configuration Register +// +//***************************************************************************** +// Left/right channel swap. +#define AM_REG_PDM_PCFG_LRSWAP_S 31 +#define AM_REG_PDM_PCFG_LRSWAP_M 0x80000000 +#define AM_REG_PDM_PCFG_LRSWAP(n) (((uint32_t)(n) << 31) & 0x80000000) +#define AM_REG_PDM_PCFG_LRSWAP_EN 0x80000000 +#define AM_REG_PDM_PCFG_LRSWAP_NOSWAP 0x00000000 + +// Right channel PGA gain. +#define AM_REG_PDM_PCFG_PGARIGHT_S 27 +#define AM_REG_PDM_PCFG_PGARIGHT_M 0x78000000 +#define AM_REG_PDM_PCFG_PGARIGHT(n) (((uint32_t)(n) << 27) & 0x78000000) +#define AM_REG_PDM_PCFG_PGARIGHT_M15DB 0x78000000 +#define AM_REG_PDM_PCFG_PGARIGHT_M300DB 0x70000000 +#define AM_REG_PDM_PCFG_PGARIGHT_M45DB 0x68000000 +#define AM_REG_PDM_PCFG_PGARIGHT_M60DB 0x60000000 +#define AM_REG_PDM_PCFG_PGARIGHT_M75DB 0x58000000 +#define AM_REG_PDM_PCFG_PGARIGHT_M90DB 0x50000000 +#define AM_REG_PDM_PCFG_PGARIGHT_M105DB 0x48000000 +#define AM_REG_PDM_PCFG_PGARIGHT_M120DB 0x40000000 +#define AM_REG_PDM_PCFG_PGARIGHT_P105DB 0x38000000 +#define AM_REG_PDM_PCFG_PGARIGHT_P90DB 0x30000000 +#define AM_REG_PDM_PCFG_PGARIGHT_P75DB 0x28000000 +#define AM_REG_PDM_PCFG_PGARIGHT_P60DB 0x20000000 +#define AM_REG_PDM_PCFG_PGARIGHT_P45DB 0x18000000 +#define AM_REG_PDM_PCFG_PGARIGHT_P30DB 0x10000000 +#define AM_REG_PDM_PCFG_PGARIGHT_P15DB 0x08000000 +#define AM_REG_PDM_PCFG_PGARIGHT_0DB 0x00000000 + +// Left channel PGA gain. +#define AM_REG_PDM_PCFG_PGALEFT_S 23 +#define AM_REG_PDM_PCFG_PGALEFT_M 0x07800000 +#define AM_REG_PDM_PCFG_PGALEFT(n) (((uint32_t)(n) << 23) & 0x07800000) +#define AM_REG_PDM_PCFG_PGALEFT_M15DB 0x07800000 +#define AM_REG_PDM_PCFG_PGALEFT_M300DB 0x07000000 +#define AM_REG_PDM_PCFG_PGALEFT_M45DB 0x06800000 +#define AM_REG_PDM_PCFG_PGALEFT_M60DB 0x06000000 +#define AM_REG_PDM_PCFG_PGALEFT_M75DB 0x05800000 +#define AM_REG_PDM_PCFG_PGALEFT_M90DB 0x05000000 +#define AM_REG_PDM_PCFG_PGALEFT_M105DB 0x04800000 +#define AM_REG_PDM_PCFG_PGALEFT_M120DB 0x04000000 +#define AM_REG_PDM_PCFG_PGALEFT_P105DB 0x03800000 +#define AM_REG_PDM_PCFG_PGALEFT_P90DB 0x03000000 +#define AM_REG_PDM_PCFG_PGALEFT_P75DB 0x02800000 +#define AM_REG_PDM_PCFG_PGALEFT_P60DB 0x02000000 +#define AM_REG_PDM_PCFG_PGALEFT_P45DB 0x01800000 +#define AM_REG_PDM_PCFG_PGALEFT_P30DB 0x01000000 +#define AM_REG_PDM_PCFG_PGALEFT_P15DB 0x00800000 +#define AM_REG_PDM_PCFG_PGALEFT_0DB 0x00000000 + +// PDM_CLK frequency divisor. +#define AM_REG_PDM_PCFG_MCLKDIV_S 17 +#define AM_REG_PDM_PCFG_MCLKDIV_M 0x00060000 +#define AM_REG_PDM_PCFG_MCLKDIV(n) (((uint32_t)(n) << 17) & 0x00060000) +#define AM_REG_PDM_PCFG_MCLKDIV_MCKDIV4 0x00060000 +#define AM_REG_PDM_PCFG_MCLKDIV_MCKDIV3 0x00040000 +#define AM_REG_PDM_PCFG_MCLKDIV_MCKDIV2 0x00020000 +#define AM_REG_PDM_PCFG_MCLKDIV_MCKDIV1 0x00000000 + +// SINC decimation rate. +#define AM_REG_PDM_PCFG_SINCRATE_S 10 +#define AM_REG_PDM_PCFG_SINCRATE_M 0x0001FC00 +#define AM_REG_PDM_PCFG_SINCRATE(n) (((uint32_t)(n) << 10) & 0x0001FC00) + +// High pass filter control. +#define AM_REG_PDM_PCFG_ADCHPD_S 9 +#define AM_REG_PDM_PCFG_ADCHPD_M 0x00000200 +#define AM_REG_PDM_PCFG_ADCHPD(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_PDM_PCFG_ADCHPD_EN 0x00000200 +#define AM_REG_PDM_PCFG_ADCHPD_DIS 0x00000000 + +// High pass filter coefficients. +#define AM_REG_PDM_PCFG_HPCUTOFF_S 5 +#define AM_REG_PDM_PCFG_HPCUTOFF_M 0x000001E0 +#define AM_REG_PDM_PCFG_HPCUTOFF(n) (((uint32_t)(n) << 5) & 0x000001E0) + +// Number of clocks during gain-setting changes. +#define AM_REG_PDM_PCFG_CYCLES_S 2 +#define AM_REG_PDM_PCFG_CYCLES_M 0x0000001C +#define AM_REG_PDM_PCFG_CYCLES(n) (((uint32_t)(n) << 2) & 0x0000001C) + +// Soft mute control. +#define AM_REG_PDM_PCFG_SOFTMUTE_S 1 +#define AM_REG_PDM_PCFG_SOFTMUTE_M 0x00000002 +#define AM_REG_PDM_PCFG_SOFTMUTE(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_PDM_PCFG_SOFTMUTE_EN 0x00000002 +#define AM_REG_PDM_PCFG_SOFTMUTE_DIS 0x00000000 + +// Data Streaming Control. +#define AM_REG_PDM_PCFG_PDMCORE_S 0 +#define AM_REG_PDM_PCFG_PDMCORE_M 0x00000001 +#define AM_REG_PDM_PCFG_PDMCORE(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_PDM_PCFG_PDMCORE_EN 0x00000001 +#define AM_REG_PDM_PCFG_PDMCORE_DIS 0x00000000 + +//***************************************************************************** +// +// PDM_VCFG - Voice Configuration Register +// +//***************************************************************************** +// Enable the IO clock. +#define AM_REG_PDM_VCFG_IOCLKEN_S 31 +#define AM_REG_PDM_VCFG_IOCLKEN_M 0x80000000 +#define AM_REG_PDM_VCFG_IOCLKEN(n) (((uint32_t)(n) << 31) & 0x80000000) +#define AM_REG_PDM_VCFG_IOCLKEN_DIS 0x00000000 +#define AM_REG_PDM_VCFG_IOCLKEN_EN 0x80000000 + +// Reset the IP core. +#define AM_REG_PDM_VCFG_RSTB_S 30 +#define AM_REG_PDM_VCFG_RSTB_M 0x40000000 +#define AM_REG_PDM_VCFG_RSTB(n) (((uint32_t)(n) << 30) & 0x40000000) +#define AM_REG_PDM_VCFG_RSTB_RESET 0x00000000 +#define AM_REG_PDM_VCFG_RSTB_NORM 0x40000000 + +// Select the PDM input clock. +#define AM_REG_PDM_VCFG_PDMCLKSEL_S 27 +#define AM_REG_PDM_VCFG_PDMCLKSEL_M 0x38000000 +#define AM_REG_PDM_VCFG_PDMCLKSEL(n) (((uint32_t)(n) << 27) & 0x38000000) +#define AM_REG_PDM_VCFG_PDMCLKSEL_DISABLE 0x00000000 +#define AM_REG_PDM_VCFG_PDMCLKSEL_12MHz 0x08000000 +#define AM_REG_PDM_VCFG_PDMCLKSEL_6MHz 0x10000000 +#define AM_REG_PDM_VCFG_PDMCLKSEL_3MHz 0x18000000 +#define AM_REG_PDM_VCFG_PDMCLKSEL_1_5MHz 0x20000000 +#define AM_REG_PDM_VCFG_PDMCLKSEL_750KHz 0x28000000 +#define AM_REG_PDM_VCFG_PDMCLKSEL_375KHz 0x30000000 +#define AM_REG_PDM_VCFG_PDMCLKSEL_187KHz 0x38000000 + +// Enable the serial clock. +#define AM_REG_PDM_VCFG_PDMCLK_S 26 +#define AM_REG_PDM_VCFG_PDMCLK_M 0x04000000 +#define AM_REG_PDM_VCFG_PDMCLK(n) (((uint32_t)(n) << 26) & 0x04000000) +#define AM_REG_PDM_VCFG_PDMCLK_DIS 0x00000000 +#define AM_REG_PDM_VCFG_PDMCLK_EN 0x04000000 + +// I2S interface enable. +#define AM_REG_PDM_VCFG_I2SMODE_S 20 +#define AM_REG_PDM_VCFG_I2SMODE_M 0x00100000 +#define AM_REG_PDM_VCFG_I2SMODE(n) (((uint32_t)(n) << 20) & 0x00100000) +#define AM_REG_PDM_VCFG_I2SMODE_DIS 0x00000000 +#define AM_REG_PDM_VCFG_I2SMODE_EN 0x00100000 + +// I2S BCLK input inversion. +#define AM_REG_PDM_VCFG_BCLKINV_S 19 +#define AM_REG_PDM_VCFG_BCLKINV_M 0x00080000 +#define AM_REG_PDM_VCFG_BCLKINV(n) (((uint32_t)(n) << 19) & 0x00080000) +#define AM_REG_PDM_VCFG_BCLKINV_INV 0x00000000 +#define AM_REG_PDM_VCFG_BCLKINV_NORM 0x00080000 + +// PDM clock sampling delay. +#define AM_REG_PDM_VCFG_DMICKDEL_S 17 +#define AM_REG_PDM_VCFG_DMICKDEL_M 0x00020000 +#define AM_REG_PDM_VCFG_DMICKDEL(n) (((uint32_t)(n) << 17) & 0x00020000) +#define AM_REG_PDM_VCFG_DMICKDEL_0CYC 0x00000000 +#define AM_REG_PDM_VCFG_DMICKDEL_1CYC 0x00020000 + +// Select PDM input clock source. +#define AM_REG_PDM_VCFG_SELAP_S 16 +#define AM_REG_PDM_VCFG_SELAP_M 0x00010000 +#define AM_REG_PDM_VCFG_SELAP(n) (((uint32_t)(n) << 16) & 0x00010000) +#define AM_REG_PDM_VCFG_SELAP_I2S 0x00010000 +#define AM_REG_PDM_VCFG_SELAP_INTERNAL 0x00000000 + +// PCM data packing enable. +#define AM_REG_PDM_VCFG_PCMPACK_S 8 +#define AM_REG_PDM_VCFG_PCMPACK_M 0x00000100 +#define AM_REG_PDM_VCFG_PCMPACK(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_PDM_VCFG_PCMPACK_DIS 0x00000000 +#define AM_REG_PDM_VCFG_PCMPACK_EN 0x00000100 + +// Set PCM channels. +#define AM_REG_PDM_VCFG_CHSET_S 3 +#define AM_REG_PDM_VCFG_CHSET_M 0x00000018 +#define AM_REG_PDM_VCFG_CHSET(n) (((uint32_t)(n) << 3) & 0x00000018) +#define AM_REG_PDM_VCFG_CHSET_DIS 0x00000000 +#define AM_REG_PDM_VCFG_CHSET_LEFT 0x00000008 +#define AM_REG_PDM_VCFG_CHSET_RIGHT 0x00000010 +#define AM_REG_PDM_VCFG_CHSET_STEREO 0x00000018 + +//***************************************************************************** +// +// PDM_FR - Voice Status Register +// +//***************************************************************************** +// Valid 32-bit entries currently in the FIFO. +#define AM_REG_PDM_FR_FIFOCNT_S 0 +#define AM_REG_PDM_FR_FIFOCNT_M 0x000001FF +#define AM_REG_PDM_FR_FIFOCNT(n) (((uint32_t)(n) << 0) & 0x000001FF) + +//***************************************************************************** +// +// PDM_FRD - FIFO Read +// +//***************************************************************************** +// FIFO read data. +#define AM_REG_PDM_FRD_FIFOREAD_S 0 +#define AM_REG_PDM_FRD_FIFOREAD_M 0xFFFFFFFF +#define AM_REG_PDM_FRD_FIFOREAD(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// PDM_FLUSH - FIFO Flush +// +//***************************************************************************** +// FIFO FLUSH. +#define AM_REG_PDM_FLUSH_FIFOFLUSH_S 0 +#define AM_REG_PDM_FLUSH_FIFOFLUSH_M 0x00000001 +#define AM_REG_PDM_FLUSH_FIFOFLUSH(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// PDM_FTHR - FIFO Threshold +// +//***************************************************************************** +// FIFO interrupt threshold. +#define AM_REG_PDM_FTHR_FIFOTHR_S 0 +#define AM_REG_PDM_FTHR_FIFOTHR_M 0x000000FF +#define AM_REG_PDM_FTHR_FIFOTHR(n) (((uint32_t)(n) << 0) & 0x000000FF) + +#endif // AM_REG_PDM_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_pwrctrl.h b/bsp/apollo2/libraries/drivers/regs/am_reg_pwrctrl.h new file mode 100644 index 0000000000..cac7cab36c --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_pwrctrl.h @@ -0,0 +1,485 @@ +//***************************************************************************** +// +// am_reg_pwrctrl.h +//! @file +//! +//! @brief Register macros for the PWRCTRL module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_PWRCTRL_H +#define AM_REG_PWRCTRL_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_PWRCTRL_NUM_MODULES 1 +#define AM_REG_PWRCTRLn(n) \ + (REG_PWRCTRL_BASEADDR + 0x00000000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_PWRCTRL_SUPPLYSRC_O 0x00000000 +#define AM_REG_PWRCTRL_POWERSTATUS_O 0x00000004 +#define AM_REG_PWRCTRL_DEVICEEN_O 0x00000008 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_O 0x0000000C +#define AM_REG_PWRCTRL_MEMEN_O 0x00000010 +#define AM_REG_PWRCTRL_PWRONSTATUS_O 0x00000014 +#define AM_REG_PWRCTRL_SRAMCTRL_O 0x00000018 +#define AM_REG_PWRCTRL_ADCSTATUS_O 0x0000001C +#define AM_REG_PWRCTRL_MISCOPT_O 0x00000020 + +//***************************************************************************** +// +// PWRCTRL_SUPPLYSRC - Memory and Core Voltage Supply Source Select Register +// +//***************************************************************************** +// Switches the CORE DOMAIN from BUCK mode (if enabled) to LDO when CPU is in +// DEEP SLEEP. If all the devices are off then this does not matter and LDO (low +// power mode) is used +#define AM_REG_PWRCTRL_SUPPLYSRC_SWITCH_LDO_IN_SLEEP_S 2 +#define AM_REG_PWRCTRL_SUPPLYSRC_SWITCH_LDO_IN_SLEEP_M 0x00000004 +#define AM_REG_PWRCTRL_SUPPLYSRC_SWITCH_LDO_IN_SLEEP(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_PWRCTRL_SUPPLYSRC_SWITCH_LDO_IN_SLEEP_EN 0x00000004 + +// Enables and Selects the Core Buck as the supply for the low-voltage power +// domain. +#define AM_REG_PWRCTRL_SUPPLYSRC_COREBUCKEN_S 1 +#define AM_REG_PWRCTRL_SUPPLYSRC_COREBUCKEN_M 0x00000002 +#define AM_REG_PWRCTRL_SUPPLYSRC_COREBUCKEN(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_PWRCTRL_SUPPLYSRC_COREBUCKEN_EN 0x00000002 + +// Enables and select the Memory Buck as the supply for the Flash and SRAM power +// domain. +#define AM_REG_PWRCTRL_SUPPLYSRC_MEMBUCKEN_S 0 +#define AM_REG_PWRCTRL_SUPPLYSRC_MEMBUCKEN_M 0x00000001 +#define AM_REG_PWRCTRL_SUPPLYSRC_MEMBUCKEN(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_PWRCTRL_SUPPLYSRC_MEMBUCKEN_EN 0x00000001 + +//***************************************************************************** +// +// PWRCTRL_POWERSTATUS - Power Status Register for MCU supplies and peripherals +// +//***************************************************************************** +// Indicates whether the Core low-voltage domain is supplied from the LDO or the +// Buck. +#define AM_REG_PWRCTRL_POWERSTATUS_COREBUCKON_S 1 +#define AM_REG_PWRCTRL_POWERSTATUS_COREBUCKON_M 0x00000002 +#define AM_REG_PWRCTRL_POWERSTATUS_COREBUCKON(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_PWRCTRL_POWERSTATUS_COREBUCKON_LDO 0x00000000 +#define AM_REG_PWRCTRL_POWERSTATUS_COREBUCKON_BUCK 0x00000002 + +// Indicate whether the Memory power domain is supplied from the LDO or the +// Buck. +#define AM_REG_PWRCTRL_POWERSTATUS_MEMBUCKON_S 0 +#define AM_REG_PWRCTRL_POWERSTATUS_MEMBUCKON_M 0x00000001 +#define AM_REG_PWRCTRL_POWERSTATUS_MEMBUCKON(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_PWRCTRL_POWERSTATUS_MEMBUCKON_LDO 0x00000000 +#define AM_REG_PWRCTRL_POWERSTATUS_MEMBUCKON_BUCK 0x00000001 + +//***************************************************************************** +// +// PWRCTRL_DEVICEEN - DEVICE ENABLES for SHELBY +// +//***************************************************************************** +// Enable PDM Digital Block +#define AM_REG_PWRCTRL_DEVICEEN_PDM_S 10 +#define AM_REG_PWRCTRL_DEVICEEN_PDM_M 0x00000400 +#define AM_REG_PWRCTRL_DEVICEEN_PDM(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_PWRCTRL_DEVICEEN_PDM_EN 0x00000400 +#define AM_REG_PWRCTRL_DEVICEEN_PDM_DIS 0x00000000 + +// Enable ADC Digital Block +#define AM_REG_PWRCTRL_DEVICEEN_ADC_S 9 +#define AM_REG_PWRCTRL_DEVICEEN_ADC_M 0x00000200 +#define AM_REG_PWRCTRL_DEVICEEN_ADC(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_PWRCTRL_DEVICEEN_ADC_EN 0x00000200 +#define AM_REG_PWRCTRL_DEVICEEN_ADC_DIS 0x00000000 + +// Enable UART 1 +#define AM_REG_PWRCTRL_DEVICEEN_UART1_S 8 +#define AM_REG_PWRCTRL_DEVICEEN_UART1_M 0x00000100 +#define AM_REG_PWRCTRL_DEVICEEN_UART1(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_PWRCTRL_DEVICEEN_UART1_EN 0x00000100 +#define AM_REG_PWRCTRL_DEVICEEN_UART1_DIS 0x00000000 + +// Enable UART 0 +#define AM_REG_PWRCTRL_DEVICEEN_UART0_S 7 +#define AM_REG_PWRCTRL_DEVICEEN_UART0_M 0x00000080 +#define AM_REG_PWRCTRL_DEVICEEN_UART0(n) (((uint32_t)(n) << 7) & 0x00000080) +#define AM_REG_PWRCTRL_DEVICEEN_UART0_EN 0x00000080 +#define AM_REG_PWRCTRL_DEVICEEN_UART0_DIS 0x00000000 + +// Enable IO MASTER 5 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER5_S 6 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER5_M 0x00000040 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER5(n) (((uint32_t)(n) << 6) & 0x00000040) +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER5_EN 0x00000040 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER5_DIS 0x00000000 + +// Enable IO MASTER 4 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER4_S 5 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER4_M 0x00000020 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER4(n) (((uint32_t)(n) << 5) & 0x00000020) +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER4_EN 0x00000020 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER4_DIS 0x00000000 + +// Enable IO MASTER 3 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER3_S 4 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER3_M 0x00000010 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER3(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER3_EN 0x00000010 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER3_DIS 0x00000000 + +// Enable IO MASTER 2 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER2_S 3 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER2_M 0x00000008 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER2(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER2_EN 0x00000008 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER2_DIS 0x00000000 + +// Enable IO MASTER 1 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER1_S 2 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER1_M 0x00000004 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER1(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER1_EN 0x00000004 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER1_DIS 0x00000000 + +// Enable IO MASTER 0 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER0_S 1 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER0_M 0x00000002 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER0(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER0_EN 0x00000002 +#define AM_REG_PWRCTRL_DEVICEEN_IO_MASTER0_DIS 0x00000000 + +// Enable IO SLAVE +#define AM_REG_PWRCTRL_DEVICEEN_IO_SLAVE_S 0 +#define AM_REG_PWRCTRL_DEVICEEN_IO_SLAVE_M 0x00000001 +#define AM_REG_PWRCTRL_DEVICEEN_IO_SLAVE(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_PWRCTRL_DEVICEEN_IO_SLAVE_EN 0x00000001 +#define AM_REG_PWRCTRL_DEVICEEN_IO_SLAVE_DIS 0x00000000 + +//***************************************************************************** +// +// PWRCTRL_SRAMPWDINSLEEP - Powerdown an SRAM Banks in Deep Sleep mode +// +//***************************************************************************** +// Enable CACHE BANKS to power down in deep sleep +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_CACHE_PWD_SLP_S 31 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_CACHE_PWD_SLP_M 0x80000000 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_CACHE_PWD_SLP(n) (((uint32_t)(n) << 31) & 0x80000000) +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_CACHE_PWD_SLP_EN 0x80000000 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_CACHE_PWD_SLP_DIS 0x00000000 + +// Selects which SRAM banks are powered down in deep sleep mode, causing the +// contents of the bank to be lost. +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_S 0 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_M 0x000007FF +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN(n) (((uint32_t)(n) << 0) & 0x000007FF) +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_NONE 0x00000000 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_GROUP0_SRAM0 0x00000001 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_GROUP0_SRAM1 0x00000002 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_GROUP0_SRAM2 0x00000004 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_GROUP0_SRAM3 0x00000008 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_GROUP1 0x00000010 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_GROUP2 0x00000020 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_GROUP3 0x00000040 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_GROUP4 0x00000080 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_GROUP5 0x00000100 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_GROUP6 0x00000200 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_GROUP7 0x00000400 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_SRAM8K 0x00000001 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_SRAM16K 0x00000003 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_SRAM32K 0x0000000F +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_SRAM64K 0x0000001F +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_SRAM128K 0x0000007F +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_ALLBUTLOWER8K 0x000007FE +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_ALLBUTLOWER16K 0x000007FC +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_ALLBUTLOWER24K 0x000007F8 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_ALLBUTLOWER32K 0x000007F0 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_ALLBUTLOWER64K 0x000007E0 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_ALLBUTLOWER128K 0x00000780 +#define AM_REG_PWRCTRL_SRAMPWDINSLEEP_SRAMSLEEPPOWERDOWN_ALL 0x000007FF + +//***************************************************************************** +// +// PWRCTRL_MEMEN - Disables individual banks of the MEMORY array +// +//***************************************************************************** +// Enable CACHE BANK 2 +#define AM_REG_PWRCTRL_MEMEN_CACHEB2_S 31 +#define AM_REG_PWRCTRL_MEMEN_CACHEB2_M 0x80000000 +#define AM_REG_PWRCTRL_MEMEN_CACHEB2(n) (((uint32_t)(n) << 31) & 0x80000000) +#define AM_REG_PWRCTRL_MEMEN_CACHEB2_EN 0x80000000 +#define AM_REG_PWRCTRL_MEMEN_CACHEB2_DIS 0x00000000 + +// Enable CACHE BANK 0 +#define AM_REG_PWRCTRL_MEMEN_CACHEB0_S 29 +#define AM_REG_PWRCTRL_MEMEN_CACHEB0_M 0x20000000 +#define AM_REG_PWRCTRL_MEMEN_CACHEB0(n) (((uint32_t)(n) << 29) & 0x20000000) +#define AM_REG_PWRCTRL_MEMEN_CACHEB0_EN 0x20000000 +#define AM_REG_PWRCTRL_MEMEN_CACHEB0_DIS 0x00000000 + +// Enable FLASH1 +#define AM_REG_PWRCTRL_MEMEN_FLASH1_S 12 +#define AM_REG_PWRCTRL_MEMEN_FLASH1_M 0x00001000 +#define AM_REG_PWRCTRL_MEMEN_FLASH1(n) (((uint32_t)(n) << 12) & 0x00001000) +#define AM_REG_PWRCTRL_MEMEN_FLASH1_EN 0x00001000 +#define AM_REG_PWRCTRL_MEMEN_FLASH1_DIS 0x00000000 + +// Enable FLASH 0 +#define AM_REG_PWRCTRL_MEMEN_FLASH0_S 11 +#define AM_REG_PWRCTRL_MEMEN_FLASH0_M 0x00000800 +#define AM_REG_PWRCTRL_MEMEN_FLASH0(n) (((uint32_t)(n) << 11) & 0x00000800) +#define AM_REG_PWRCTRL_MEMEN_FLASH0_EN 0x00000800 +#define AM_REG_PWRCTRL_MEMEN_FLASH0_DIS 0x00000000 + +// Enables power for selected SRAM banks (else an access to its address space to +// generate a Hard Fault). +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_S 0 +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_M 0x000007FF +#define AM_REG_PWRCTRL_MEMEN_SRAMEN(n) (((uint32_t)(n) << 0) & 0x000007FF) +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_NONE 0x00000000 +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP0_SRAM0 0x00000001 +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP0_SRAM1 0x00000002 +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP0_SRAM2 0x00000004 +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP0_SRAM3 0x00000008 +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP1 0x00000010 +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP2 0x00000020 +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP3 0x00000040 +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP4 0x00000080 +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP5 0x00000100 +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP6 0x00000200 +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_GROUP7 0x00000400 +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM8K 0x00000001 +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM16K 0x00000003 +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM32K 0x0000000F +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM64K 0x0000001F +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM128K 0x0000007F +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_SRAM256K 0x000007FF +#define AM_REG_PWRCTRL_MEMEN_SRAMEN_ALL 0x000007FF + +//***************************************************************************** +// +// PWRCTRL_PWRONSTATUS - POWER ON Status +// +//***************************************************************************** +// This bit is 1 if power is supplied to CACHE BANK 2 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_CACHEB2_S 21 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_CACHEB2_M 0x00200000 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_CACHEB2(n) (((uint32_t)(n) << 21) & 0x00200000) + +// This bit is 1 if power is supplied to CACHE BANK 0 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_CACHEB0_S 19 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_CACHEB0_M 0x00080000 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_CACHEB0(n) (((uint32_t)(n) << 19) & 0x00080000) + +// This bit is 1 if power is supplied to SRAM domain PD_GRP7 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP7_SRAM_S 18 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP7_SRAM_M 0x00040000 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP7_SRAM(n) (((uint32_t)(n) << 18) & 0x00040000) + +// This bit is 1 if power is supplied to SRAM domain PD_GRP6 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP6_SRAM_S 17 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP6_SRAM_M 0x00020000 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP6_SRAM(n) (((uint32_t)(n) << 17) & 0x00020000) + +// This bit is 1 if power is supplied to SRAM domain PD_GRP5 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP5_SRAM_S 16 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP5_SRAM_M 0x00010000 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP5_SRAM(n) (((uint32_t)(n) << 16) & 0x00010000) + +// This bit is 1 if power is supplied to SRAM domain PD_GRP4 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP4_SRAM_S 15 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP4_SRAM_M 0x00008000 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP4_SRAM(n) (((uint32_t)(n) << 15) & 0x00008000) + +// This bit is 1 if power is supplied to SRAM domain PD_GRP3 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP3_SRAM_S 14 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP3_SRAM_M 0x00004000 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP3_SRAM(n) (((uint32_t)(n) << 14) & 0x00004000) + +// This bit is 1 if power is supplied to SRAM domain PD_GRP2 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP2_SRAM_S 13 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP2_SRAM_M 0x00002000 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP2_SRAM(n) (((uint32_t)(n) << 13) & 0x00002000) + +// This bit is 1 if power is supplied to SRAM domain PD_GRP1 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP1_SRAM_S 12 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP1_SRAM_M 0x00001000 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP1_SRAM(n) (((uint32_t)(n) << 12) & 0x00001000) + +// This bit is 1 if power is supplied to SRAM domain PD_SRAM0_3 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM3_S 11 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM3_M 0x00000800 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM3(n) (((uint32_t)(n) << 11) & 0x00000800) + +// This bit is 1 if power is supplied to SRAM domain PD_SRAM0_2 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM2_S 10 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM2_M 0x00000400 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM2(n) (((uint32_t)(n) << 10) & 0x00000400) + +// This bit is 1 if power is supplied to SRAM domain SRAM0_1 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM1_S 9 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM1_M 0x00000200 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM1(n) (((uint32_t)(n) << 9) & 0x00000200) + +// This bit is 1 if power is supplied to SRAM domain SRAM0_0 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM0_S 8 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM0_M 0x00000100 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_GRP0_SRAM0(n) (((uint32_t)(n) << 8) & 0x00000100) + +// This bit is 1 if power is supplied to domain PD_ADC +#define AM_REG_PWRCTRL_PWRONSTATUS_PDADC_S 7 +#define AM_REG_PWRCTRL_PWRONSTATUS_PDADC_M 0x00000080 +#define AM_REG_PWRCTRL_PWRONSTATUS_PDADC(n) (((uint32_t)(n) << 7) & 0x00000080) + +// This bit is 1 if power is supplied to domain PD_FLAM1 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_FLAM1_S 6 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_FLAM1_M 0x00000040 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_FLAM1(n) (((uint32_t)(n) << 6) & 0x00000040) + +// This bit is 1 if power is supplied to domain PD_FLAM0 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_FLAM0_S 5 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_FLAM0_M 0x00000020 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_FLAM0(n) (((uint32_t)(n) << 5) & 0x00000020) + +// This bit is 1 if power is supplied to domain PD_PDM +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_PDM_S 4 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_PDM_M 0x00000010 +#define AM_REG_PWRCTRL_PWRONSTATUS_PD_PDM(n) (((uint32_t)(n) << 4) & 0x00000010) + +// This bit is 1 if power is supplied to power domain C, which supplies IOM3-5. +#define AM_REG_PWRCTRL_PWRONSTATUS_PDC_S 3 +#define AM_REG_PWRCTRL_PWRONSTATUS_PDC_M 0x00000008 +#define AM_REG_PWRCTRL_PWRONSTATUS_PDC(n) (((uint32_t)(n) << 3) & 0x00000008) + +// This bit is 1 if power is supplied to power domain B, which supplies IOM0-2. +#define AM_REG_PWRCTRL_PWRONSTATUS_PDB_S 2 +#define AM_REG_PWRCTRL_PWRONSTATUS_PDB_M 0x00000004 +#define AM_REG_PWRCTRL_PWRONSTATUS_PDB(n) (((uint32_t)(n) << 2) & 0x00000004) + +// This bit is 1 if power is supplied to power domain A, which supplies IOS and +// UART0,1. +#define AM_REG_PWRCTRL_PWRONSTATUS_PDA_S 1 +#define AM_REG_PWRCTRL_PWRONSTATUS_PDA_M 0x00000002 +#define AM_REG_PWRCTRL_PWRONSTATUS_PDA(n) (((uint32_t)(n) << 1) & 0x00000002) + +//***************************************************************************** +// +// PWRCTRL_SRAMCTRL - SRAM Control register +// +//***************************************************************************** +// Enables top-level clock gating in the SRAM block. This bit should be enabled +// for lowest power operation. +#define AM_REG_PWRCTRL_SRAMCTRL_SRAM_MASTER_CLKGATE_S 2 +#define AM_REG_PWRCTRL_SRAMCTRL_SRAM_MASTER_CLKGATE_M 0x00000004 +#define AM_REG_PWRCTRL_SRAMCTRL_SRAM_MASTER_CLKGATE(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_PWRCTRL_SRAMCTRL_SRAM_MASTER_CLKGATE_EN 0x00000004 +#define AM_REG_PWRCTRL_SRAMCTRL_SRAM_MASTER_CLKGATE_DIS 0x00000000 + +// Enables individual per-RAM clock gating in the SRAM block. This bit should +// be enabled for lowest power operation. +#define AM_REG_PWRCTRL_SRAMCTRL_SRAM_CLKGATE_S 1 +#define AM_REG_PWRCTRL_SRAMCTRL_SRAM_CLKGATE_M 0x00000002 +#define AM_REG_PWRCTRL_SRAMCTRL_SRAM_CLKGATE(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_PWRCTRL_SRAMCTRL_SRAM_CLKGATE_EN 0x00000002 +#define AM_REG_PWRCTRL_SRAMCTRL_SRAM_CLKGATE_DIS 0x00000000 + +// Enable LS (light sleep) of cache RAMs. When this bit is set, the RAMS will +// be put into light sleep mode while inactive. NOTE: if the SRAM is actively +// used, this may have an adverse affect on power since entering/exiting LS mode +// may consume more power than would be saved. +#define AM_REG_PWRCTRL_SRAMCTRL_SRAM_LIGHT_SLEEP_S 0 +#define AM_REG_PWRCTRL_SRAMCTRL_SRAM_LIGHT_SLEEP_M 0x00000001 +#define AM_REG_PWRCTRL_SRAMCTRL_SRAM_LIGHT_SLEEP(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_PWRCTRL_SRAMCTRL_SRAM_LIGHT_SLEEP_EN 0x00000001 +#define AM_REG_PWRCTRL_SRAMCTRL_SRAM_LIGHT_SLEEP_DIS 0x00000000 + +//***************************************************************************** +// +// PWRCTRL_ADCSTATUS - Power Status Register for ADC Block +// +//***************************************************************************** +// This bit indicates that the ADC REFBUF is powered down +#define AM_REG_PWRCTRL_ADCSTATUS_ADC_REFBUF_PWD_S 5 +#define AM_REG_PWRCTRL_ADCSTATUS_ADC_REFBUF_PWD_M 0x00000020 +#define AM_REG_PWRCTRL_ADCSTATUS_ADC_REFBUF_PWD(n) (((uint32_t)(n) << 5) & 0x00000020) + +// This bit indicates that the ADC REFKEEP is powered down +#define AM_REG_PWRCTRL_ADCSTATUS_ADC_REFKEEP_PWD_S 4 +#define AM_REG_PWRCTRL_ADCSTATUS_ADC_REFKEEP_PWD_M 0x00000010 +#define AM_REG_PWRCTRL_ADCSTATUS_ADC_REFKEEP_PWD(n) (((uint32_t)(n) << 4) & 0x00000010) + +// This bit indicates that the ADC VBAT resistor divider is powered down +#define AM_REG_PWRCTRL_ADCSTATUS_ADC_VBAT_PWD_S 3 +#define AM_REG_PWRCTRL_ADCSTATUS_ADC_VBAT_PWD_M 0x00000008 +#define AM_REG_PWRCTRL_ADCSTATUS_ADC_VBAT_PWD(n) (((uint32_t)(n) << 3) & 0x00000008) + +// This bit indicates that the ADC temperature sensor input buffer is powered +// down +#define AM_REG_PWRCTRL_ADCSTATUS_ADC_VPTAT_PWD_S 2 +#define AM_REG_PWRCTRL_ADCSTATUS_ADC_VPTAT_PWD_M 0x00000004 +#define AM_REG_PWRCTRL_ADCSTATUS_ADC_VPTAT_PWD(n) (((uint32_t)(n) << 2) & 0x00000004) + +// This bit indicates that the ADC Band Gap is powered down +#define AM_REG_PWRCTRL_ADCSTATUS_ADC_BGT_PWD_S 1 +#define AM_REG_PWRCTRL_ADCSTATUS_ADC_BGT_PWD_M 0x00000002 +#define AM_REG_PWRCTRL_ADCSTATUS_ADC_BGT_PWD(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This bit indicates that the ADC is powered down +#define AM_REG_PWRCTRL_ADCSTATUS_ADC_PWD_S 0 +#define AM_REG_PWRCTRL_ADCSTATUS_ADC_PWD_M 0x00000001 +#define AM_REG_PWRCTRL_ADCSTATUS_ADC_PWD(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// PWRCTRL_MISCOPT - Power Optimization Control Bits +// +//***************************************************************************** +// Setting this bit will enable the MEM LDO to be in LPMODE during deep sleep +// even when the ctimers or stimers are running +#define AM_REG_PWRCTRL_MISCOPT_DIS_LDOLPMODE_TIMERS_S 2 +#define AM_REG_PWRCTRL_MISCOPT_DIS_LDOLPMODE_TIMERS_M 0x00000004 +#define AM_REG_PWRCTRL_MISCOPT_DIS_LDOLPMODE_TIMERS(n) (((uint32_t)(n) << 2) & 0x00000004) + +#endif // AM_REG_PWRCTRL_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_rstgen.h b/bsp/apollo2/libraries/drivers/regs/am_reg_rstgen.h new file mode 100644 index 0000000000..1e76519744 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_rstgen.h @@ -0,0 +1,211 @@ +//***************************************************************************** +// +// am_reg_rstgen.h +//! @file +//! +//! @brief Register macros for the RSTGEN module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_RSTGEN_H +#define AM_REG_RSTGEN_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_RSTGEN_NUM_MODULES 1 +#define AM_REG_RSTGENn(n) \ + (REG_RSTGEN_BASEADDR + 0x00000000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_RSTGEN_CFG_O 0x00000000 +#define AM_REG_RSTGEN_SWPOI_O 0x00000004 +#define AM_REG_RSTGEN_SWPOR_O 0x00000008 +#define AM_REG_RSTGEN_STAT_O 0x0000000C +#define AM_REG_RSTGEN_CLRSTAT_O 0x00000010 +#define AM_REG_RSTGEN_TPIU_RST_O 0x00000014 +#define AM_REG_RSTGEN_INTEN_O 0x00000200 +#define AM_REG_RSTGEN_INTSTAT_O 0x00000204 +#define AM_REG_RSTGEN_INTCLR_O 0x00000208 +#define AM_REG_RSTGEN_INTSET_O 0x0000020C + +//***************************************************************************** +// +// RSTGEN_INTEN - Reset Interrupt register: Enable +// +//***************************************************************************** +// Enables an interrupt that triggers when VCC is below BODH level. +#define AM_REG_RSTGEN_INTEN_BODH_S 0 +#define AM_REG_RSTGEN_INTEN_BODH_M 0x00000001 +#define AM_REG_RSTGEN_INTEN_BODH(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// RSTGEN_INTSTAT - Reset Interrupt register: Status +// +//***************************************************************************** +// Enables an interrupt that triggers when VCC is below BODH level. +#define AM_REG_RSTGEN_INTSTAT_BODH_S 0 +#define AM_REG_RSTGEN_INTSTAT_BODH_M 0x00000001 +#define AM_REG_RSTGEN_INTSTAT_BODH(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// RSTGEN_INTCLR - Reset Interrupt register: Clear +// +//***************************************************************************** +// Enables an interrupt that triggers when VCC is below BODH level. +#define AM_REG_RSTGEN_INTCLR_BODH_S 0 +#define AM_REG_RSTGEN_INTCLR_BODH_M 0x00000001 +#define AM_REG_RSTGEN_INTCLR_BODH(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// RSTGEN_INTSET - Reset Interrupt register: Set +// +//***************************************************************************** +// Enables an interrupt that triggers when VCC is below BODH level. +#define AM_REG_RSTGEN_INTSET_BODH_S 0 +#define AM_REG_RSTGEN_INTSET_BODH_M 0x00000001 +#define AM_REG_RSTGEN_INTSET_BODH(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// RSTGEN_CFG - Configuration Register +// +//***************************************************************************** +// Watchdog Timer Reset Enable. NOTE: The WDT module must also be configured +// for WDT reset. +#define AM_REG_RSTGEN_CFG_WDREN_S 1 +#define AM_REG_RSTGEN_CFG_WDREN_M 0x00000002 +#define AM_REG_RSTGEN_CFG_WDREN(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Brown out high (2.1v) reset enable. +#define AM_REG_RSTGEN_CFG_BODHREN_S 0 +#define AM_REG_RSTGEN_CFG_BODHREN_M 0x00000001 +#define AM_REG_RSTGEN_CFG_BODHREN(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// RSTGEN_SWPOI - Software POI Reset +// +//***************************************************************************** +// 0x1B generates a software POI reset. +#define AM_REG_RSTGEN_SWPOI_SWPOIKEY_S 0 +#define AM_REG_RSTGEN_SWPOI_SWPOIKEY_M 0x000000FF +#define AM_REG_RSTGEN_SWPOI_SWPOIKEY(n) (((uint32_t)(n) << 0) & 0x000000FF) +#define AM_REG_RSTGEN_SWPOI_SWPOIKEY_KEYVALUE 0x0000001B + +//***************************************************************************** +// +// RSTGEN_SWPOR - Software POR Reset +// +//***************************************************************************** +// 0xD4 generates a software POR reset. +#define AM_REG_RSTGEN_SWPOR_SWPORKEY_S 0 +#define AM_REG_RSTGEN_SWPOR_SWPORKEY_M 0x000000FF +#define AM_REG_RSTGEN_SWPOR_SWPORKEY(n) (((uint32_t)(n) << 0) & 0x000000FF) +#define AM_REG_RSTGEN_SWPOR_SWPORKEY_KEYVALUE 0x000000D4 + +//***************************************************************************** +// +// RSTGEN_STAT - Status Register +// +//***************************************************************************** +// Reset was initiated by a Watchdog Timer Reset. +#define AM_REG_RSTGEN_STAT_WDRSTAT_S 6 +#define AM_REG_RSTGEN_STAT_WDRSTAT_M 0x00000040 +#define AM_REG_RSTGEN_STAT_WDRSTAT(n) (((uint32_t)(n) << 6) & 0x00000040) + +// Reset was a initiated by Debugger Reset. +#define AM_REG_RSTGEN_STAT_DBGRSTAT_S 5 +#define AM_REG_RSTGEN_STAT_DBGRSTAT_M 0x00000020 +#define AM_REG_RSTGEN_STAT_DBGRSTAT(n) (((uint32_t)(n) << 5) & 0x00000020) + +// Reset was a initiated by Software POI Reset. +#define AM_REG_RSTGEN_STAT_POIRSTAT_S 4 +#define AM_REG_RSTGEN_STAT_POIRSTAT_M 0x00000010 +#define AM_REG_RSTGEN_STAT_POIRSTAT(n) (((uint32_t)(n) << 4) & 0x00000010) + +// Reset was a initiated by SW POR or AIRCR Reset. +#define AM_REG_RSTGEN_STAT_SWRSTAT_S 3 +#define AM_REG_RSTGEN_STAT_SWRSTAT_M 0x00000008 +#define AM_REG_RSTGEN_STAT_SWRSTAT(n) (((uint32_t)(n) << 3) & 0x00000008) + +// Reset was initiated by a Brown-Out Reset. +#define AM_REG_RSTGEN_STAT_BORSTAT_S 2 +#define AM_REG_RSTGEN_STAT_BORSTAT_M 0x00000004 +#define AM_REG_RSTGEN_STAT_BORSTAT(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Reset was initiated by a Power-On Reset. +#define AM_REG_RSTGEN_STAT_PORSTAT_S 1 +#define AM_REG_RSTGEN_STAT_PORSTAT_M 0x00000002 +#define AM_REG_RSTGEN_STAT_PORSTAT(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Reset was initiated by an External Reset. +#define AM_REG_RSTGEN_STAT_EXRSTAT_S 0 +#define AM_REG_RSTGEN_STAT_EXRSTAT_M 0x00000001 +#define AM_REG_RSTGEN_STAT_EXRSTAT(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// RSTGEN_CLRSTAT - Clear the status register +// +//***************************************************************************** +// Writing a 1 to this bit clears all bits in the RST_STAT. +#define AM_REG_RSTGEN_CLRSTAT_CLRSTAT_S 0 +#define AM_REG_RSTGEN_CLRSTAT_CLRSTAT_M 0x00000001 +#define AM_REG_RSTGEN_CLRSTAT_CLRSTAT(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// RSTGEN_TPIU_RST - TPIU reset +// +//***************************************************************************** +// Static reset for the TPIU. Write to '1' to assert reset to TPIU. Write to '0' +// to clear the reset. +#define AM_REG_RSTGEN_TPIU_RST_TPIURST_S 0 +#define AM_REG_RSTGEN_TPIU_RST_TPIURST_M 0x00000001 +#define AM_REG_RSTGEN_TPIU_RST_TPIURST(n) (((uint32_t)(n) << 0) & 0x00000001) + +#endif // AM_REG_RSTGEN_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_rtc.h b/bsp/apollo2/libraries/drivers/regs/am_reg_rtc.h new file mode 100644 index 0000000000..9da5bc816c --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_rtc.h @@ -0,0 +1,326 @@ +//***************************************************************************** +// +// am_reg_rtc.h +//! @file +//! +//! @brief Register macros for the RTC module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_RTC_H +#define AM_REG_RTC_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_RTC_NUM_MODULES 1 +#define AM_REG_RTCn(n) \ + (REG_RTC_BASEADDR + 0x00000000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_RTC_CTRLOW_O 0x00000040 +#define AM_REG_RTC_CTRUP_O 0x00000044 +#define AM_REG_RTC_ALMLOW_O 0x00000048 +#define AM_REG_RTC_ALMUP_O 0x0000004C +#define AM_REG_RTC_RTCCTL_O 0x00000050 +#define AM_REG_RTC_INTEN_O 0x00000100 +#define AM_REG_RTC_INTSTAT_O 0x00000104 +#define AM_REG_RTC_INTCLR_O 0x00000108 +#define AM_REG_RTC_INTSET_O 0x0000010C + +//***************************************************************************** +// +// RTC_INTEN - RTC Interrupt Register: Enable +// +//***************************************************************************** +// RTC Alarm interrupt +#define AM_REG_RTC_INTEN_ALM_S 3 +#define AM_REG_RTC_INTEN_ALM_M 0x00000008 +#define AM_REG_RTC_INTEN_ALM(n) (((uint32_t)(n) << 3) & 0x00000008) + +// XT Oscillator Fail interrupt +#define AM_REG_RTC_INTEN_OF_S 2 +#define AM_REG_RTC_INTEN_OF_M 0x00000004 +#define AM_REG_RTC_INTEN_OF(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Autocalibration Complete interrupt +#define AM_REG_RTC_INTEN_ACC_S 1 +#define AM_REG_RTC_INTEN_ACC_M 0x00000002 +#define AM_REG_RTC_INTEN_ACC(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Autocalibration Fail interrupt +#define AM_REG_RTC_INTEN_ACF_S 0 +#define AM_REG_RTC_INTEN_ACF_M 0x00000001 +#define AM_REG_RTC_INTEN_ACF(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// RTC_INTSTAT - RTC Interrupt Register: Status +// +//***************************************************************************** +// RTC Alarm interrupt +#define AM_REG_RTC_INTSTAT_ALM_S 3 +#define AM_REG_RTC_INTSTAT_ALM_M 0x00000008 +#define AM_REG_RTC_INTSTAT_ALM(n) (((uint32_t)(n) << 3) & 0x00000008) + +// XT Oscillator Fail interrupt +#define AM_REG_RTC_INTSTAT_OF_S 2 +#define AM_REG_RTC_INTSTAT_OF_M 0x00000004 +#define AM_REG_RTC_INTSTAT_OF(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Autocalibration Complete interrupt +#define AM_REG_RTC_INTSTAT_ACC_S 1 +#define AM_REG_RTC_INTSTAT_ACC_M 0x00000002 +#define AM_REG_RTC_INTSTAT_ACC(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Autocalibration Fail interrupt +#define AM_REG_RTC_INTSTAT_ACF_S 0 +#define AM_REG_RTC_INTSTAT_ACF_M 0x00000001 +#define AM_REG_RTC_INTSTAT_ACF(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// RTC_INTCLR - RTC Interrupt Register: Clear +// +//***************************************************************************** +// RTC Alarm interrupt +#define AM_REG_RTC_INTCLR_ALM_S 3 +#define AM_REG_RTC_INTCLR_ALM_M 0x00000008 +#define AM_REG_RTC_INTCLR_ALM(n) (((uint32_t)(n) << 3) & 0x00000008) + +// XT Oscillator Fail interrupt +#define AM_REG_RTC_INTCLR_OF_S 2 +#define AM_REG_RTC_INTCLR_OF_M 0x00000004 +#define AM_REG_RTC_INTCLR_OF(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Autocalibration Complete interrupt +#define AM_REG_RTC_INTCLR_ACC_S 1 +#define AM_REG_RTC_INTCLR_ACC_M 0x00000002 +#define AM_REG_RTC_INTCLR_ACC(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Autocalibration Fail interrupt +#define AM_REG_RTC_INTCLR_ACF_S 0 +#define AM_REG_RTC_INTCLR_ACF_M 0x00000001 +#define AM_REG_RTC_INTCLR_ACF(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// RTC_INTSET - RTC Interrupt Register: Set +// +//***************************************************************************** +// RTC Alarm interrupt +#define AM_REG_RTC_INTSET_ALM_S 3 +#define AM_REG_RTC_INTSET_ALM_M 0x00000008 +#define AM_REG_RTC_INTSET_ALM(n) (((uint32_t)(n) << 3) & 0x00000008) + +// XT Oscillator Fail interrupt +#define AM_REG_RTC_INTSET_OF_S 2 +#define AM_REG_RTC_INTSET_OF_M 0x00000004 +#define AM_REG_RTC_INTSET_OF(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Autocalibration Complete interrupt +#define AM_REG_RTC_INTSET_ACC_S 1 +#define AM_REG_RTC_INTSET_ACC_M 0x00000002 +#define AM_REG_RTC_INTSET_ACC(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Autocalibration Fail interrupt +#define AM_REG_RTC_INTSET_ACF_S 0 +#define AM_REG_RTC_INTSET_ACF_M 0x00000001 +#define AM_REG_RTC_INTSET_ACF(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// RTC_CTRLOW - RTC Counters Lower +// +//***************************************************************************** +// Hours Counter +#define AM_REG_RTC_CTRLOW_CTRHR_S 24 +#define AM_REG_RTC_CTRLOW_CTRHR_M 0x3F000000 +#define AM_REG_RTC_CTRLOW_CTRHR(n) (((uint32_t)(n) << 24) & 0x3F000000) + +// Minutes Counter +#define AM_REG_RTC_CTRLOW_CTRMIN_S 16 +#define AM_REG_RTC_CTRLOW_CTRMIN_M 0x007F0000 +#define AM_REG_RTC_CTRLOW_CTRMIN(n) (((uint32_t)(n) << 16) & 0x007F0000) + +// Seconds Counter +#define AM_REG_RTC_CTRLOW_CTRSEC_S 8 +#define AM_REG_RTC_CTRLOW_CTRSEC_M 0x00007F00 +#define AM_REG_RTC_CTRLOW_CTRSEC(n) (((uint32_t)(n) << 8) & 0x00007F00) + +// 100ths of a second Counter +#define AM_REG_RTC_CTRLOW_CTR100_S 0 +#define AM_REG_RTC_CTRLOW_CTR100_M 0x000000FF +#define AM_REG_RTC_CTRLOW_CTR100(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// RTC_CTRUP - RTC Counters Upper +// +//***************************************************************************** +// Counter read error status +#define AM_REG_RTC_CTRUP_CTERR_S 31 +#define AM_REG_RTC_CTRUP_CTERR_M 0x80000000 +#define AM_REG_RTC_CTRUP_CTERR(n) (((uint32_t)(n) << 31) & 0x80000000) +#define AM_REG_RTC_CTRUP_CTERR_NOERR 0x00000000 +#define AM_REG_RTC_CTRUP_CTERR_RDERR 0x80000000 + +// Century enable +#define AM_REG_RTC_CTRUP_CEB_S 28 +#define AM_REG_RTC_CTRUP_CEB_M 0x10000000 +#define AM_REG_RTC_CTRUP_CEB(n) (((uint32_t)(n) << 28) & 0x10000000) +#define AM_REG_RTC_CTRUP_CEB_DIS 0x00000000 +#define AM_REG_RTC_CTRUP_CEB_EN 0x10000000 + +// Century +#define AM_REG_RTC_CTRUP_CB_S 27 +#define AM_REG_RTC_CTRUP_CB_M 0x08000000 +#define AM_REG_RTC_CTRUP_CB(n) (((uint32_t)(n) << 27) & 0x08000000) +#define AM_REG_RTC_CTRUP_CB_2000 0x00000000 +#define AM_REG_RTC_CTRUP_CB_1900_2100 0x08000000 + +// Weekdays Counter +#define AM_REG_RTC_CTRUP_CTRWKDY_S 24 +#define AM_REG_RTC_CTRUP_CTRWKDY_M 0x07000000 +#define AM_REG_RTC_CTRUP_CTRWKDY(n) (((uint32_t)(n) << 24) & 0x07000000) + +// Years Counter +#define AM_REG_RTC_CTRUP_CTRYR_S 16 +#define AM_REG_RTC_CTRUP_CTRYR_M 0x00FF0000 +#define AM_REG_RTC_CTRUP_CTRYR(n) (((uint32_t)(n) << 16) & 0x00FF0000) + +// Months Counter +#define AM_REG_RTC_CTRUP_CTRMO_S 8 +#define AM_REG_RTC_CTRUP_CTRMO_M 0x00001F00 +#define AM_REG_RTC_CTRUP_CTRMO(n) (((uint32_t)(n) << 8) & 0x00001F00) + +// Date Counter +#define AM_REG_RTC_CTRUP_CTRDATE_S 0 +#define AM_REG_RTC_CTRUP_CTRDATE_M 0x0000003F +#define AM_REG_RTC_CTRUP_CTRDATE(n) (((uint32_t)(n) << 0) & 0x0000003F) + +//***************************************************************************** +// +// RTC_ALMLOW - RTC Alarms Lower +// +//***************************************************************************** +// Hours Alarm +#define AM_REG_RTC_ALMLOW_ALMHR_S 24 +#define AM_REG_RTC_ALMLOW_ALMHR_M 0x3F000000 +#define AM_REG_RTC_ALMLOW_ALMHR(n) (((uint32_t)(n) << 24) & 0x3F000000) + +// Minutes Alarm +#define AM_REG_RTC_ALMLOW_ALMMIN_S 16 +#define AM_REG_RTC_ALMLOW_ALMMIN_M 0x007F0000 +#define AM_REG_RTC_ALMLOW_ALMMIN(n) (((uint32_t)(n) << 16) & 0x007F0000) + +// Seconds Alarm +#define AM_REG_RTC_ALMLOW_ALMSEC_S 8 +#define AM_REG_RTC_ALMLOW_ALMSEC_M 0x00007F00 +#define AM_REG_RTC_ALMLOW_ALMSEC(n) (((uint32_t)(n) << 8) & 0x00007F00) + +// 100ths of a second Alarm +#define AM_REG_RTC_ALMLOW_ALM100_S 0 +#define AM_REG_RTC_ALMLOW_ALM100_M 0x000000FF +#define AM_REG_RTC_ALMLOW_ALM100(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// RTC_ALMUP - RTC Alarms Upper +// +//***************************************************************************** +// Weekdays Alarm +#define AM_REG_RTC_ALMUP_ALMWKDY_S 16 +#define AM_REG_RTC_ALMUP_ALMWKDY_M 0x00070000 +#define AM_REG_RTC_ALMUP_ALMWKDY(n) (((uint32_t)(n) << 16) & 0x00070000) + +// Months Alarm +#define AM_REG_RTC_ALMUP_ALMMO_S 8 +#define AM_REG_RTC_ALMUP_ALMMO_M 0x00001F00 +#define AM_REG_RTC_ALMUP_ALMMO(n) (((uint32_t)(n) << 8) & 0x00001F00) + +// Date Alarm +#define AM_REG_RTC_ALMUP_ALMDATE_S 0 +#define AM_REG_RTC_ALMUP_ALMDATE_M 0x0000003F +#define AM_REG_RTC_ALMUP_ALMDATE(n) (((uint32_t)(n) << 0) & 0x0000003F) + +//***************************************************************************** +// +// RTC_RTCCTL - RTC Control Register +// +//***************************************************************************** +// Hours Counter mode +#define AM_REG_RTC_RTCCTL_HR1224_S 5 +#define AM_REG_RTC_RTCCTL_HR1224_M 0x00000020 +#define AM_REG_RTC_RTCCTL_HR1224(n) (((uint32_t)(n) << 5) & 0x00000020) +#define AM_REG_RTC_RTCCTL_HR1224_24HR 0x00000000 +#define AM_REG_RTC_RTCCTL_HR1224_12HR 0x00000020 + +// RTC input clock control +#define AM_REG_RTC_RTCCTL_RSTOP_S 4 +#define AM_REG_RTC_RTCCTL_RSTOP_M 0x00000010 +#define AM_REG_RTC_RTCCTL_RSTOP(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_RTC_RTCCTL_RSTOP_RUN 0x00000000 +#define AM_REG_RTC_RTCCTL_RSTOP_STOP 0x00000010 + +// Alarm repeat interval +#define AM_REG_RTC_RTCCTL_RPT_S 1 +#define AM_REG_RTC_RTCCTL_RPT_M 0x0000000E +#define AM_REG_RTC_RTCCTL_RPT(n) (((uint32_t)(n) << 1) & 0x0000000E) +#define AM_REG_RTC_RTCCTL_RPT_DIS 0x00000000 +#define AM_REG_RTC_RTCCTL_RPT_YEAR 0x00000002 +#define AM_REG_RTC_RTCCTL_RPT_MONTH 0x00000004 +#define AM_REG_RTC_RTCCTL_RPT_WEEK 0x00000006 +#define AM_REG_RTC_RTCCTL_RPT_DAY 0x00000008 +#define AM_REG_RTC_RTCCTL_RPT_HR 0x0000000A +#define AM_REG_RTC_RTCCTL_RPT_MIN 0x0000000C +#define AM_REG_RTC_RTCCTL_RPT_SEC 0x0000000E + +// Counter write control +#define AM_REG_RTC_RTCCTL_WRTC_S 0 +#define AM_REG_RTC_RTCCTL_WRTC_M 0x00000001 +#define AM_REG_RTC_RTCCTL_WRTC(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_RTC_RTCCTL_WRTC_DIS 0x00000000 +#define AM_REG_RTC_RTCCTL_WRTC_EN 0x00000001 + +#endif // AM_REG_RTC_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_sysctrl.h b/bsp/apollo2/libraries/drivers/regs/am_reg_sysctrl.h new file mode 100644 index 0000000000..4a00cc21d5 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_sysctrl.h @@ -0,0 +1,653 @@ +//***************************************************************************** +// +// am_reg_sysctrl.h +//! @file +//! +//! @brief Register macros for the SYSCTRL module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_SYSCTRL_H +#define AM_REG_SYSCTRL_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_SYSCTRL_NUM_MODULES 1 +#define AM_REG_SYSCTRLn(n) \ + (REG_SYSCTRL_BASEADDR + 0x00000000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_SYSCTRL_ICSR_O 0xE000ED04 +#define AM_REG_SYSCTRL_VTOR_O 0xE000ED08 +#define AM_REG_SYSCTRL_AIRCR_O 0xE000ED0C +#define AM_REG_SYSCTRL_SCR_O 0xE000ED10 +#define AM_REG_SYSCTRL_CCR_O 0xE000ED14 +#define AM_REG_SYSCTRL_SHPR1_O 0xE000ED18 +#define AM_REG_SYSCTRL_SHPR2_O 0xE000ED1C +#define AM_REG_SYSCTRL_SHPR3_O 0xE000ED20 +#define AM_REG_SYSCTRL_SHCSR_O 0xE000ED24 +#define AM_REG_SYSCTRL_CFSR_O 0xE000ED28 +#define AM_REG_SYSCTRL_HFSR_O 0xE000ED2C +#define AM_REG_SYSCTRL_MMFAR_O 0xE000ED34 +#define AM_REG_SYSCTRL_BFAR_O 0xE000ED38 +#define AM_REG_SYSCTRL_CPACR_O 0xE000ED88 +#define AM_REG_SYSCTRL_DEMCR_O 0xE000EDFC +#define AM_REG_SYSCTRL_STIR_O 0xE000EF00 +#define AM_REG_SYSCTRL_FPCCR_O 0xE000EF34 +#define AM_REG_SYSCTRL_FPCAR_O 0xE000EF38 +#define AM_REG_SYSCTRL_FPDSCR_O 0xE000EF3C + +//***************************************************************************** +// +// SYSCTRL_ICSR - Interrupt Control and State Register +// +//***************************************************************************** +// Pend an NMI exception. +#define AM_REG_SYSCTRL_ICSR_NMIPENDSET_S 31 +#define AM_REG_SYSCTRL_ICSR_NMIPENDSET_M 0x80000000 +#define AM_REG_SYSCTRL_ICSR_NMIPENDSET(n) (((uint32_t)(n) << 31) & 0x80000000) + +// Set the PendSV interrupt as pending. +#define AM_REG_SYSCTRL_ICSR_PENDSVSET_S 28 +#define AM_REG_SYSCTRL_ICSR_PENDSVSET_M 0x10000000 +#define AM_REG_SYSCTRL_ICSR_PENDSVSET(n) (((uint32_t)(n) << 28) & 0x10000000) + +// Remove the pending status of the PendSV exception. +#define AM_REG_SYSCTRL_ICSR_PENDSVCLR_S 27 +#define AM_REG_SYSCTRL_ICSR_PENDSVCLR_M 0x08000000 +#define AM_REG_SYSCTRL_ICSR_PENDSVCLR(n) (((uint32_t)(n) << 27) & 0x08000000) + +// Set the SysTick exception as pending. +#define AM_REG_SYSCTRL_ICSR_PENDSTSET_S 26 +#define AM_REG_SYSCTRL_ICSR_PENDSTSET_M 0x04000000 +#define AM_REG_SYSCTRL_ICSR_PENDSTSET(n) (((uint32_t)(n) << 26) & 0x04000000) + +// Remove the pending status of the SysTick exception. +#define AM_REG_SYSCTRL_ICSR_PENDSTCLR_S 25 +#define AM_REG_SYSCTRL_ICSR_PENDSTCLR_M 0x02000000 +#define AM_REG_SYSCTRL_ICSR_PENDSTCLR(n) (((uint32_t)(n) << 25) & 0x02000000) + +// Indicates whether a pending exception will be serviced on exit from debug +// halt state. +#define AM_REG_SYSCTRL_ICSR_ISRPREEMPT_S 23 +#define AM_REG_SYSCTRL_ICSR_ISRPREEMPT_M 0x00800000 +#define AM_REG_SYSCTRL_ICSR_ISRPREEMPT(n) (((uint32_t)(n) << 23) & 0x00800000) + +// Indicates whether an external interrupt, generated by the NVIC, is pending. +#define AM_REG_SYSCTRL_ICSR_ISRPENDING_S 22 +#define AM_REG_SYSCTRL_ICSR_ISRPENDING_M 0x00400000 +#define AM_REG_SYSCTRL_ICSR_ISRPENDING(n) (((uint32_t)(n) << 22) & 0x00400000) + +// The exception number of the highest priority pending exception. +#define AM_REG_SYSCTRL_ICSR_VECTPENDING_S 12 +#define AM_REG_SYSCTRL_ICSR_VECTPENDING_M 0x001FF000 +#define AM_REG_SYSCTRL_ICSR_VECTPENDING(n) (((uint32_t)(n) << 12) & 0x001FF000) + +// Indicates whether there is an active exception other than the exception shown +// by IPSR. +#define AM_REG_SYSCTRL_ICSR_RETTOBASE_S 11 +#define AM_REG_SYSCTRL_ICSR_RETTOBASE_M 0x00000800 +#define AM_REG_SYSCTRL_ICSR_RETTOBASE(n) (((uint32_t)(n) << 11) & 0x00000800) + +// The exception number of the current executing exception. +#define AM_REG_SYSCTRL_ICSR_VECTACTIVE_S 0 +#define AM_REG_SYSCTRL_ICSR_VECTACTIVE_M 0x000001FF +#define AM_REG_SYSCTRL_ICSR_VECTACTIVE(n) (((uint32_t)(n) << 0) & 0x000001FF) + +//***************************************************************************** +// +// SYSCTRL_VTOR - Vector Table Offset Register. +// +//***************************************************************************** +// Vector table base address. +#define AM_REG_SYSCTRL_VTOR_VALUE_S 0 +#define AM_REG_SYSCTRL_VTOR_VALUE_M 0xFFFFFFFF +#define AM_REG_SYSCTRL_VTOR_VALUE(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// SYSCTRL_AIRCR - Application Interrupt and Reset Control Register. +// +//***************************************************************************** +// Register writes must write 0x5FA to this field, otherwise the write is +// ignored. +#define AM_REG_SYSCTRL_AIRCR_VECTKEY_S 16 +#define AM_REG_SYSCTRL_AIRCR_VECTKEY_M 0xFFFF0000 +#define AM_REG_SYSCTRL_AIRCR_VECTKEY(n) (((uint32_t)(n) << 16) & 0xFFFF0000) + +// Indicates endianness of memory architecture. (Little = 0, Big = 1) +#define AM_REG_SYSCTRL_AIRCR_ENDIANNESS_S 15 +#define AM_REG_SYSCTRL_AIRCR_ENDIANNESS_M 0x00008000 +#define AM_REG_SYSCTRL_AIRCR_ENDIANNESS(n) (((uint32_t)(n) << 15) & 0x00008000) + +// Priority grouping, indicates the binary point position. +#define AM_REG_SYSCTRL_AIRCR_PRIGROUP_S 8 +#define AM_REG_SYSCTRL_AIRCR_PRIGROUP_M 0x00000700 +#define AM_REG_SYSCTRL_AIRCR_PRIGROUP(n) (((uint32_t)(n) << 8) & 0x00000700) + +// Writing a 1 to this bit reqests a local reset. +#define AM_REG_SYSCTRL_AIRCR_SYSRESETREQ_S 2 +#define AM_REG_SYSCTRL_AIRCR_SYSRESETREQ_M 0x00000004 +#define AM_REG_SYSCTRL_AIRCR_SYSRESETREQ(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Writing a 1 to this bit clears all active state information for fixed and +// configurable exceptions. +#define AM_REG_SYSCTRL_AIRCR_VECTCLRACTIVE_S 1 +#define AM_REG_SYSCTRL_AIRCR_VECTCLRACTIVE_M 0x00000002 +#define AM_REG_SYSCTRL_AIRCR_VECTCLRACTIVE(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Writing a 1 to this bit causes a local system reset. +#define AM_REG_SYSCTRL_AIRCR_VECTRESET_S 0 +#define AM_REG_SYSCTRL_AIRCR_VECTRESET_M 0x00000001 +#define AM_REG_SYSCTRL_AIRCR_VECTRESET(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// SYSCTRL_SCR - System Control Register. +// +//***************************************************************************** +// Determines whether a pending interrupt is a wakeup event. +#define AM_REG_SYSCTRL_SCR_SEVONPEND_S 4 +#define AM_REG_SYSCTRL_SCR_SEVONPEND_M 0x00000010 +#define AM_REG_SYSCTRL_SCR_SEVONPEND(n) (((uint32_t)(n) << 4) & 0x00000010) + +// Determines whether the sleep mode should be regular or deep sleep +#define AM_REG_SYSCTRL_SCR_SLEEPDEEP_S 2 +#define AM_REG_SYSCTRL_SCR_SLEEPDEEP_M 0x00000004 +#define AM_REG_SYSCTRL_SCR_SLEEPDEEP(n) (((uint32_t)(n) << 2) & 0x00000004) + +// Determines whether the processor shoudl automatically sleep when an ISR +// returns to the base-level. +#define AM_REG_SYSCTRL_SCR_SLEEPONEXIT_S 1 +#define AM_REG_SYSCTRL_SCR_SLEEPONEXIT_M 0x00000002 +#define AM_REG_SYSCTRL_SCR_SLEEPONEXIT(n) (((uint32_t)(n) << 1) & 0x00000002) + +//***************************************************************************** +// +// SYSCTRL_CCR - Configuration and Control Register. +// +//***************************************************************************** +// Set to force 8-byte alignment for the stack pointer. +#define AM_REG_SYSCTRL_CCR_STKALIGN_S 9 +#define AM_REG_SYSCTRL_CCR_STKALIGN_M 0x00000200 +#define AM_REG_SYSCTRL_CCR_STKALIGN(n) (((uint32_t)(n) << 9) & 0x00000200) + +// Set to ignore precise data access faults during hard fault handlers. +#define AM_REG_SYSCTRL_CCR_BFHFNMIGN_S 8 +#define AM_REG_SYSCTRL_CCR_BFHFNMIGN_M 0x00000100 +#define AM_REG_SYSCTRL_CCR_BFHFNMIGN(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Set to enable trapping on divide-by-zero. +#define AM_REG_SYSCTRL_CCR_DIV0TRP_S 4 +#define AM_REG_SYSCTRL_CCR_DIV0TRP_M 0x00000010 +#define AM_REG_SYSCTRL_CCR_DIV0TRP(n) (((uint32_t)(n) << 4) & 0x00000010) + +// Set to enable trapping of unaligned word or halfword accesses. +#define AM_REG_SYSCTRL_CCR_UNALIGNTRP_S 3 +#define AM_REG_SYSCTRL_CCR_UNALIGNTRP_M 0x00000008 +#define AM_REG_SYSCTRL_CCR_UNALIGNTRP(n) (((uint32_t)(n) << 3) & 0x00000008) + +// Set to allow unpriveleged software to access the STIR +#define AM_REG_SYSCTRL_CCR_USERSETMPEND_S 1 +#define AM_REG_SYSCTRL_CCR_USERSETMPEND_M 0x00000002 +#define AM_REG_SYSCTRL_CCR_USERSETMPEND(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Set to enable the processor to enter Thread mode at an execution priority +// other than base level. +#define AM_REG_SYSCTRL_CCR_NONBASETHRDENA_S 0 +#define AM_REG_SYSCTRL_CCR_NONBASETHRDENA_M 0x00000001 +#define AM_REG_SYSCTRL_CCR_NONBASETHRDENA(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// SYSCTRL_SHPR1 - System Handler Priority Register 1. +// +//***************************************************************************** +// Reserved for priority of system handler 7. +#define AM_REG_SYSCTRL_SHPR1_PRI_7_S 24 +#define AM_REG_SYSCTRL_SHPR1_PRI_7_M 0xFF000000 +#define AM_REG_SYSCTRL_SHPR1_PRI_7(n) (((uint32_t)(n) << 24) & 0xFF000000) + +// Priority of system handler 6, UsageFault. +#define AM_REG_SYSCTRL_SHPR1_PRI_6_S 16 +#define AM_REG_SYSCTRL_SHPR1_PRI_6_M 0x00FF0000 +#define AM_REG_SYSCTRL_SHPR1_PRI_6(n) (((uint32_t)(n) << 16) & 0x00FF0000) + +// Priority of system handler 5, BusFault. +#define AM_REG_SYSCTRL_SHPR1_PRI_5_S 8 +#define AM_REG_SYSCTRL_SHPR1_PRI_5_M 0x0000FF00 +#define AM_REG_SYSCTRL_SHPR1_PRI_5(n) (((uint32_t)(n) << 8) & 0x0000FF00) + +// Priority of system handler 4, MemManage. +#define AM_REG_SYSCTRL_SHPR1_PRI_4_S 0 +#define AM_REG_SYSCTRL_SHPR1_PRI_4_M 0x000000FF +#define AM_REG_SYSCTRL_SHPR1_PRI_4(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// SYSCTRL_SHPR2 - System Handler Priority Register 2. +// +//***************************************************************************** +// Priority of system handler 11, SVCall. +#define AM_REG_SYSCTRL_SHPR2_PRI_11_S 24 +#define AM_REG_SYSCTRL_SHPR2_PRI_11_M 0xFF000000 +#define AM_REG_SYSCTRL_SHPR2_PRI_11(n) (((uint32_t)(n) << 24) & 0xFF000000) + +// Reserved for priority of system handler 10. +#define AM_REG_SYSCTRL_SHPR2_PRI_10_S 16 +#define AM_REG_SYSCTRL_SHPR2_PRI_10_M 0x00FF0000 +#define AM_REG_SYSCTRL_SHPR2_PRI_10(n) (((uint32_t)(n) << 16) & 0x00FF0000) + +// Reserved for priority of system handler 9. +#define AM_REG_SYSCTRL_SHPR2_PRI_9_S 8 +#define AM_REG_SYSCTRL_SHPR2_PRI_9_M 0x0000FF00 +#define AM_REG_SYSCTRL_SHPR2_PRI_9(n) (((uint32_t)(n) << 8) & 0x0000FF00) + +// Reserved for priority of system handler 8. +#define AM_REG_SYSCTRL_SHPR2_PRI_8_S 0 +#define AM_REG_SYSCTRL_SHPR2_PRI_8_M 0x000000FF +#define AM_REG_SYSCTRL_SHPR2_PRI_8(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// SYSCTRL_SHPR3 - System Handler Priority Register 3. +// +//***************************************************************************** +// Priority of system handler 15, SysTick. +#define AM_REG_SYSCTRL_SHPR3_PRI_15_S 24 +#define AM_REG_SYSCTRL_SHPR3_PRI_15_M 0xFF000000 +#define AM_REG_SYSCTRL_SHPR3_PRI_15(n) (((uint32_t)(n) << 24) & 0xFF000000) + +// Priority of system handler 14, PendSV. +#define AM_REG_SYSCTRL_SHPR3_PRI_14_S 16 +#define AM_REG_SYSCTRL_SHPR3_PRI_14_M 0x00FF0000 +#define AM_REG_SYSCTRL_SHPR3_PRI_14(n) (((uint32_t)(n) << 16) & 0x00FF0000) + +// Reserved for priority of system handler 13. +#define AM_REG_SYSCTRL_SHPR3_PRI_13_S 8 +#define AM_REG_SYSCTRL_SHPR3_PRI_13_M 0x0000FF00 +#define AM_REG_SYSCTRL_SHPR3_PRI_13(n) (((uint32_t)(n) << 8) & 0x0000FF00) + +// Priority of system handler 12, DebugMonitor. +#define AM_REG_SYSCTRL_SHPR3_PRI_12_S 0 +#define AM_REG_SYSCTRL_SHPR3_PRI_12_M 0x000000FF +#define AM_REG_SYSCTRL_SHPR3_PRI_12(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// SYSCTRL_SHCSR - System Handler Control and State Register. +// +//***************************************************************************** +// Set to enable UsageFault. +#define AM_REG_SYSCTRL_SHCSR_USAGEFAULTENA_S 18 +#define AM_REG_SYSCTRL_SHCSR_USAGEFAULTENA_M 0x00040000 +#define AM_REG_SYSCTRL_SHCSR_USAGEFAULTENA(n) (((uint32_t)(n) << 18) & 0x00040000) + +// Set to enable BusFault. +#define AM_REG_SYSCTRL_SHCSR_BUSFAULTENA_S 17 +#define AM_REG_SYSCTRL_SHCSR_BUSFAULTENA_M 0x00020000 +#define AM_REG_SYSCTRL_SHCSR_BUSFAULTENA(n) (((uint32_t)(n) << 17) & 0x00020000) + +// Set to enable MemManageFault. +#define AM_REG_SYSCTRL_SHCSR_MEMFAULTENA_S 16 +#define AM_REG_SYSCTRL_SHCSR_MEMFAULTENA_M 0x00010000 +#define AM_REG_SYSCTRL_SHCSR_MEMFAULTENA(n) (((uint32_t)(n) << 16) & 0x00010000) + +// Set to pend the SVCall exception. +#define AM_REG_SYSCTRL_SHCSR_SVCALLPENDED_S 15 +#define AM_REG_SYSCTRL_SHCSR_SVCALLPENDED_M 0x00008000 +#define AM_REG_SYSCTRL_SHCSR_SVCALLPENDED(n) (((uint32_t)(n) << 15) & 0x00008000) + +// Set to pend the BusFault exception. +#define AM_REG_SYSCTRL_SHCSR_BUSFAULTPENDED_S 14 +#define AM_REG_SYSCTRL_SHCSR_BUSFAULTPENDED_M 0x00004000 +#define AM_REG_SYSCTRL_SHCSR_BUSFAULTPENDED(n) (((uint32_t)(n) << 14) & 0x00004000) + +// Set to pend the MemManageFault exception. +#define AM_REG_SYSCTRL_SHCSR_MEMFAULTPENDED_S 13 +#define AM_REG_SYSCTRL_SHCSR_MEMFAULTPENDED_M 0x00002000 +#define AM_REG_SYSCTRL_SHCSR_MEMFAULTPENDED(n) (((uint32_t)(n) << 13) & 0x00002000) + +// Set to pend the UsageFault exception. +#define AM_REG_SYSCTRL_SHCSR_USGFAULTPENDED_S 12 +#define AM_REG_SYSCTRL_SHCSR_USGFAULTPENDED_M 0x00001000 +#define AM_REG_SYSCTRL_SHCSR_USGFAULTPENDED(n) (((uint32_t)(n) << 12) & 0x00001000) + +// Set when SysTick is active. +#define AM_REG_SYSCTRL_SHCSR_SYSTICKACT_S 11 +#define AM_REG_SYSCTRL_SHCSR_SYSTICKACT_M 0x00000800 +#define AM_REG_SYSCTRL_SHCSR_SYSTICKACT(n) (((uint32_t)(n) << 11) & 0x00000800) + +// Set when PendSV is active. +#define AM_REG_SYSCTRL_SHCSR_PENDSVACT_S 10 +#define AM_REG_SYSCTRL_SHCSR_PENDSVACT_M 0x00000400 +#define AM_REG_SYSCTRL_SHCSR_PENDSVACT(n) (((uint32_t)(n) << 10) & 0x00000400) + +// Set when Monitor is active. +#define AM_REG_SYSCTRL_SHCSR_MONITORACT_S 8 +#define AM_REG_SYSCTRL_SHCSR_MONITORACT_M 0x00000100 +#define AM_REG_SYSCTRL_SHCSR_MONITORACT(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Set when SVCall is active. +#define AM_REG_SYSCTRL_SHCSR_SVCALLACT_S 7 +#define AM_REG_SYSCTRL_SHCSR_SVCALLACT_M 0x00000080 +#define AM_REG_SYSCTRL_SHCSR_SVCALLACT(n) (((uint32_t)(n) << 7) & 0x00000080) + +// Set when UsageFault is active. +#define AM_REG_SYSCTRL_SHCSR_USGFAULTACT_S 3 +#define AM_REG_SYSCTRL_SHCSR_USGFAULTACT_M 0x00000008 +#define AM_REG_SYSCTRL_SHCSR_USGFAULTACT(n) (((uint32_t)(n) << 3) & 0x00000008) + +// Set when BusFault is active. +#define AM_REG_SYSCTRL_SHCSR_BUSFAULTACT_S 1 +#define AM_REG_SYSCTRL_SHCSR_BUSFAULTACT_M 0x00000002 +#define AM_REG_SYSCTRL_SHCSR_BUSFAULTACT(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Set when MemManageFault is active. +#define AM_REG_SYSCTRL_SHCSR_MEMFAULTACT_S 0 +#define AM_REG_SYSCTRL_SHCSR_MEMFAULTACT_M 0x00000001 +#define AM_REG_SYSCTRL_SHCSR_MEMFAULTACT(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// SYSCTRL_CFSR - Configurable Fault Status Register. +// +//***************************************************************************** +// Divide by zero error has occurred. +#define AM_REG_SYSCTRL_CFSR_DIVBYZERO_S 25 +#define AM_REG_SYSCTRL_CFSR_DIVBYZERO_M 0x02000000 +#define AM_REG_SYSCTRL_CFSR_DIVBYZERO(n) (((uint32_t)(n) << 25) & 0x02000000) + +// Unaligned access error has occurred. +#define AM_REG_SYSCTRL_CFSR_UNALIGNED_S 24 +#define AM_REG_SYSCTRL_CFSR_UNALIGNED_M 0x01000000 +#define AM_REG_SYSCTRL_CFSR_UNALIGNED(n) (((uint32_t)(n) << 24) & 0x01000000) + +// A coprocessor access error has occurred. +#define AM_REG_SYSCTRL_CFSR_NOCP_S 19 +#define AM_REG_SYSCTRL_CFSR_NOCP_M 0x00080000 +#define AM_REG_SYSCTRL_CFSR_NOCP(n) (((uint32_t)(n) << 19) & 0x00080000) + +// An integrity check error has occurred on EXC_RETURN. +#define AM_REG_SYSCTRL_CFSR_INVPC_S 18 +#define AM_REG_SYSCTRL_CFSR_INVPC_M 0x00040000 +#define AM_REG_SYSCTRL_CFSR_INVPC(n) (((uint32_t)(n) << 18) & 0x00040000) + +// Instruction executed with invalid EPSR.T or EPSR.IT field. +#define AM_REG_SYSCTRL_CFSR_INVSTATE_S 17 +#define AM_REG_SYSCTRL_CFSR_INVSTATE_M 0x00020000 +#define AM_REG_SYSCTRL_CFSR_INVSTATE(n) (((uint32_t)(n) << 17) & 0x00020000) + +// Processor attempted to execute an undefined instruction. +#define AM_REG_SYSCTRL_CFSR_UNDEFINSTR_S 16 +#define AM_REG_SYSCTRL_CFSR_UNDEFINSTR_M 0x00010000 +#define AM_REG_SYSCTRL_CFSR_UNDEFINSTR(n) (((uint32_t)(n) << 16) & 0x00010000) + +// BFAR has valid contents. +#define AM_REG_SYSCTRL_CFSR_BFARVALID_S 15 +#define AM_REG_SYSCTRL_CFSR_BFARVALID_M 0x00008000 +#define AM_REG_SYSCTRL_CFSR_BFARVALID(n) (((uint32_t)(n) << 15) & 0x00008000) + +// A bus fault occurred during FP lazy state preservation. +#define AM_REG_SYSCTRL_CFSR_LSPERR_S 13 +#define AM_REG_SYSCTRL_CFSR_LSPERR_M 0x00002000 +#define AM_REG_SYSCTRL_CFSR_LSPERR(n) (((uint32_t)(n) << 13) & 0x00002000) + +// A derived bus fault has occurred on exception entry. +#define AM_REG_SYSCTRL_CFSR_STKERR_S 12 +#define AM_REG_SYSCTRL_CFSR_STKERR_M 0x00001000 +#define AM_REG_SYSCTRL_CFSR_STKERR(n) (((uint32_t)(n) << 12) & 0x00001000) + +// A derived bus fault has occurred on exception return. +#define AM_REG_SYSCTRL_CFSR_UNSTKERR_S 11 +#define AM_REG_SYSCTRL_CFSR_UNSTKERR_M 0x00000800 +#define AM_REG_SYSCTRL_CFSR_UNSTKERR(n) (((uint32_t)(n) << 11) & 0x00000800) + +// Imprecise data access error has occurred. +#define AM_REG_SYSCTRL_CFSR_IMPRECISERR_S 10 +#define AM_REG_SYSCTRL_CFSR_IMPRECISERR_M 0x00000400 +#define AM_REG_SYSCTRL_CFSR_IMPRECISERR(n) (((uint32_t)(n) << 10) & 0x00000400) + +// A precise data access has occurrred. The faulting address is in BFAR. +#define AM_REG_SYSCTRL_CFSR_PRECISERR_S 9 +#define AM_REG_SYSCTRL_CFSR_PRECISERR_M 0x00000200 +#define AM_REG_SYSCTRL_CFSR_PRECISERR(n) (((uint32_t)(n) << 9) & 0x00000200) + +// A bus fault on an instruction prefetch has occurred. +#define AM_REG_SYSCTRL_CFSR_IBUSERR_S 8 +#define AM_REG_SYSCTRL_CFSR_IBUSERR_M 0x00000100 +#define AM_REG_SYSCTRL_CFSR_IBUSERR(n) (((uint32_t)(n) << 8) & 0x00000100) + +// MMAR has valid contents. +#define AM_REG_SYSCTRL_CFSR_MMARVALID_S 7 +#define AM_REG_SYSCTRL_CFSR_MMARVALID_M 0x00000080 +#define AM_REG_SYSCTRL_CFSR_MMARVALID(n) (((uint32_t)(n) << 7) & 0x00000080) + +// MemManage fault occurred during FP lazy state preservation. +#define AM_REG_SYSCTRL_CFSR_MLSPERR_S 5 +#define AM_REG_SYSCTRL_CFSR_MLSPERR_M 0x00000020 +#define AM_REG_SYSCTRL_CFSR_MLSPERR(n) (((uint32_t)(n) << 5) & 0x00000020) + +// Derived MemManage fault occurred on exception entry. +#define AM_REG_SYSCTRL_CFSR_MSTKERR_S 4 +#define AM_REG_SYSCTRL_CFSR_MSTKERR_M 0x00000010 +#define AM_REG_SYSCTRL_CFSR_MSTKERR(n) (((uint32_t)(n) << 4) & 0x00000010) + +// Derived MemManage fault occurred on exception return. +#define AM_REG_SYSCTRL_CFSR_MUNSTKER_S 3 +#define AM_REG_SYSCTRL_CFSR_MUNSTKER_M 0x00000008 +#define AM_REG_SYSCTRL_CFSR_MUNSTKER(n) (((uint32_t)(n) << 3) & 0x00000008) + +// Data access violation. Address is in MMAR. +#define AM_REG_SYSCTRL_CFSR_DACCVIOL_S 1 +#define AM_REG_SYSCTRL_CFSR_DACCVIOL_M 0x00000002 +#define AM_REG_SYSCTRL_CFSR_DACCVIOL(n) (((uint32_t)(n) << 1) & 0x00000002) + +// MPU or Execute Never default memory map access violation. +#define AM_REG_SYSCTRL_CFSR_IACCVIOL_S 0 +#define AM_REG_SYSCTRL_CFSR_IACCVIOL_M 0x00000001 +#define AM_REG_SYSCTRL_CFSR_IACCVIOL(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// SYSCTRL_HFSR - Hard Fault Status Register. +// +//***************************************************************************** +// Debug event has occurred. +#define AM_REG_SYSCTRL_HFSR_DEBUGEVT_S 31 +#define AM_REG_SYSCTRL_HFSR_DEBUGEVT_M 0x80000000 +#define AM_REG_SYSCTRL_HFSR_DEBUGEVT(n) (((uint32_t)(n) << 31) & 0x80000000) + +// Processor has elevated a configurable-priority fault to a HardFault. +#define AM_REG_SYSCTRL_HFSR_FORCED_S 30 +#define AM_REG_SYSCTRL_HFSR_FORCED_M 0x40000000 +#define AM_REG_SYSCTRL_HFSR_FORCED(n) (((uint32_t)(n) << 30) & 0x40000000) + +// Vector table read fault has occurred. +#define AM_REG_SYSCTRL_HFSR_VECTTBL_S 1 +#define AM_REG_SYSCTRL_HFSR_VECTTBL_M 0x00000002 +#define AM_REG_SYSCTRL_HFSR_VECTTBL(n) (((uint32_t)(n) << 1) & 0x00000002) + +//***************************************************************************** +// +// SYSCTRL_MMFAR - MemManage Fault Address Register. +// +//***************************************************************************** +// Address of the memory location that caused an MMU fault. +#define AM_REG_SYSCTRL_MMFAR_ADDRESS_S 0 +#define AM_REG_SYSCTRL_MMFAR_ADDRESS_M 0xFFFFFFFF +#define AM_REG_SYSCTRL_MMFAR_ADDRESS(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// SYSCTRL_BFAR - Bus Fault Address Register. +// +//***************************************************************************** +// Address of the memory location that caused an Bus fault. +#define AM_REG_SYSCTRL_BFAR_ADDRESS_S 0 +#define AM_REG_SYSCTRL_BFAR_ADDRESS_M 0xFFFFFFFF +#define AM_REG_SYSCTRL_BFAR_ADDRESS(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// SYSCTRL_CPACR - Coprocessor Access Control Register. +// +//***************************************************************************** +// Access priveleges for the Floating point unit. Must always match CP10. +#define AM_REG_SYSCTRL_CPACR_CP11_S 22 +#define AM_REG_SYSCTRL_CPACR_CP11_M 0x00C00000 +#define AM_REG_SYSCTRL_CPACR_CP11(n) (((uint32_t)(n) << 22) & 0x00C00000) + +// Access priveleges for the Floating point unit. Must always match CP11. +#define AM_REG_SYSCTRL_CPACR_CP10_S 20 +#define AM_REG_SYSCTRL_CPACR_CP10_M 0x00300000 +#define AM_REG_SYSCTRL_CPACR_CP10(n) (((uint32_t)(n) << 20) & 0x00300000) + +//***************************************************************************** +// +// SYSCTRL_DEMCR - Debug Exception and Monitor Control Register +// +//***************************************************************************** +// Global enable for all DWT and ITM features. +#define AM_REG_SYSCTRL_DEMCR_TRCENA_S 24 +#define AM_REG_SYSCTRL_DEMCR_TRCENA_M 0x01000000 +#define AM_REG_SYSCTRL_DEMCR_TRCENA(n) (((uint32_t)(n) << 24) & 0x01000000) + +//***************************************************************************** +// +// SYSCTRL_STIR - Software Triggered Interrupt Register +// +//***************************************************************************** +// Vector number of the interrupt that should be triggered. +#define AM_REG_SYSCTRL_STIR_INTID_S 0 +#define AM_REG_SYSCTRL_STIR_INTID_M 0xFFFFFFFF +#define AM_REG_SYSCTRL_STIR_INTID(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// SYSCTRL_FPCCR - Floating-Point Context Control Register. +// +//***************************************************************************** +// Set to enable automatic saving of FP registers on exception entry. +#define AM_REG_SYSCTRL_FPCCR_ASPEN_S 31 +#define AM_REG_SYSCTRL_FPCCR_ASPEN_M 0x80000000 +#define AM_REG_SYSCTRL_FPCCR_ASPEN(n) (((uint32_t)(n) << 31) & 0x80000000) + +// Set to enable lazy context saving of FP registers on exception entry. +#define AM_REG_SYSCTRL_FPCCR_LSPEN_S 30 +#define AM_REG_SYSCTRL_FPCCR_LSPEN_M 0x40000000 +#define AM_REG_SYSCTRL_FPCCR_LSPEN(n) (((uint32_t)(n) << 30) & 0x40000000) + +// Able to set DebugMonitor exception to pending on last FP stack allocation. +#define AM_REG_SYSCTRL_FPCCR_MONRDY_S 8 +#define AM_REG_SYSCTRL_FPCCR_MONRDY_M 0x00000100 +#define AM_REG_SYSCTRL_FPCCR_MONRDY(n) (((uint32_t)(n) << 8) & 0x00000100) + +// Able to set BusFault exception to pending on last FP stack allocation. +#define AM_REG_SYSCTRL_FPCCR_BFRDY_S 6 +#define AM_REG_SYSCTRL_FPCCR_BFRDY_M 0x00000040 +#define AM_REG_SYSCTRL_FPCCR_BFRDY(n) (((uint32_t)(n) << 6) & 0x00000040) + +// Able to set MemManage exception to pending on last FP stack allocation. +#define AM_REG_SYSCTRL_FPCCR_MMRDY_S 5 +#define AM_REG_SYSCTRL_FPCCR_MMRDY_M 0x00000020 +#define AM_REG_SYSCTRL_FPCCR_MMRDY(n) (((uint32_t)(n) << 5) & 0x00000020) + +// Able to set HardFault exception to pending on last FP stack allocation. +#define AM_REG_SYSCTRL_FPCCR_HFRDY_S 4 +#define AM_REG_SYSCTRL_FPCCR_HFRDY_M 0x00000010 +#define AM_REG_SYSCTRL_FPCCR_HFRDY(n) (((uint32_t)(n) << 4) & 0x00000010) + +// Running from Thread mode on last FP stack allocation. +#define AM_REG_SYSCTRL_FPCCR_THREAD_S 3 +#define AM_REG_SYSCTRL_FPCCR_THREAD_M 0x00000008 +#define AM_REG_SYSCTRL_FPCCR_THREAD(n) (((uint32_t)(n) << 3) & 0x00000008) + +// Running from unprivileged mode on last FP stack allocation. +#define AM_REG_SYSCTRL_FPCCR_USER_S 1 +#define AM_REG_SYSCTRL_FPCCR_USER_M 0x00000002 +#define AM_REG_SYSCTRL_FPCCR_USER(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Lazy state preservation is active. +#define AM_REG_SYSCTRL_FPCCR_LSPACT_S 0 +#define AM_REG_SYSCTRL_FPCCR_LSPACT_M 0x00000001 +#define AM_REG_SYSCTRL_FPCCR_LSPACT(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// SYSCTRL_FPCAR - Floating-Point Context Address Register. +// +//***************************************************************************** +// Address of the unpopulated floating-point register space allocated on the +// exception stack frame. +#define AM_REG_SYSCTRL_FPCAR_ADDRESS_S 0 +#define AM_REG_SYSCTRL_FPCAR_ADDRESS_M 0xFFFFFFFF +#define AM_REG_SYSCTRL_FPCAR_ADDRESS(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) + +//***************************************************************************** +// +// SYSCTRL_FPDSCR - Floating-Point Default Status Control Register. +// +//***************************************************************************** +// Default value for FPSCR.AHP. +#define AM_REG_SYSCTRL_FPDSCR_AHP_S 26 +#define AM_REG_SYSCTRL_FPDSCR_AHP_M 0x04000000 +#define AM_REG_SYSCTRL_FPDSCR_AHP(n) (((uint32_t)(n) << 26) & 0x04000000) + +// Default value for FPSCR.DN. +#define AM_REG_SYSCTRL_FPDSCR_DN_S 25 +#define AM_REG_SYSCTRL_FPDSCR_DN_M 0x02000000 +#define AM_REG_SYSCTRL_FPDSCR_DN(n) (((uint32_t)(n) << 25) & 0x02000000) + +// Default value for FPSCR.FZ. +#define AM_REG_SYSCTRL_FPDSCR_FZ_S 24 +#define AM_REG_SYSCTRL_FPDSCR_FZ_M 0x01000000 +#define AM_REG_SYSCTRL_FPDSCR_FZ(n) (((uint32_t)(n) << 24) & 0x01000000) + +// Default value for FPSCR.RMode. +#define AM_REG_SYSCTRL_FPDSCR_RMODE_S 22 +#define AM_REG_SYSCTRL_FPDSCR_RMODE_M 0x00C00000 +#define AM_REG_SYSCTRL_FPDSCR_RMODE(n) (((uint32_t)(n) << 22) & 0x00C00000) + +#endif // AM_REG_SYSCTRL_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_systick.h b/bsp/apollo2/libraries/drivers/regs/am_reg_systick.h new file mode 100644 index 0000000000..d68a8c4063 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_systick.h @@ -0,0 +1,137 @@ +//***************************************************************************** +// +// am_reg_systick.h +//! @file +//! +//! @brief Register macros for the SYSTICK module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_SYSTICK_H +#define AM_REG_SYSTICK_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_SYSTICK_NUM_MODULES 1 +#define AM_REG_SYSTICKn(n) \ + (REG_SYSTICK_BASEADDR + 0x00000000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_SYSTICK_SYSTCSR_O 0xE000E010 +#define AM_REG_SYSTICK_SYSTRVR_O 0xE000E014 +#define AM_REG_SYSTICK_SYSTCVR_O 0xE000E018 +#define AM_REG_SYSTICK_SYSTCALIB_O 0xE000E01C + +//***************************************************************************** +// +// SYSTICK_SYSTCSR - SysTick Control and Status Register. +// +//***************************************************************************** +// Returns 1 if timer counted to 0 since last time this was read. +#define AM_REG_SYSTICK_SYSTCSR_COUNTFLAG_S 16 +#define AM_REG_SYSTICK_SYSTCSR_COUNTFLAG_M 0x00010000 +#define AM_REG_SYSTICK_SYSTCSR_COUNTFLAG(n) (((uint32_t)(n) << 16) & 0x00010000) + +// Enables SysTick exception request. Software can use COUNTFLAG to determine if +// SysTick has ever counted to zero. 0 = counting down to zero does not assert +// the SysTick exception request; 1 = counting down to zero asserts the SysTick +// exception request. +#define AM_REG_SYSTICK_SYSTCSR_TICKINT_S 1 +#define AM_REG_SYSTICK_SYSTCSR_TICKINT_M 0x00000002 +#define AM_REG_SYSTICK_SYSTCSR_TICKINT(n) (((uint32_t)(n) << 1) & 0x00000002) + +// Enables the counter. 0 = counter disabled; 1 = counter enabled. +#define AM_REG_SYSTICK_SYSTCSR_ENABLE_S 0 +#define AM_REG_SYSTICK_SYSTCSR_ENABLE_M 0x00000001 +#define AM_REG_SYSTICK_SYSTCSR_ENABLE(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// SYSTICK_SYSTRVR - SysTick Reload Value Register. +// +//***************************************************************************** +// Value to load into the SYSTCVR register when the counter is enabled and when +// it reaches 0. +#define AM_REG_SYSTICK_SYSTRVR_RELOAD_S 0 +#define AM_REG_SYSTICK_SYSTRVR_RELOAD_M 0x00FFFFFF +#define AM_REG_SYSTICK_SYSTRVR_RELOAD(n) (((uint32_t)(n) << 0) & 0x00FFFFFF) + +//***************************************************************************** +// +// SYSTICK_SYSTCVR - SysTick Current Value Register. +// +//***************************************************************************** +// Reads return the current value of the SysTick counter. A write of any value +// clears the field to 0, and also clears the SYSTCSR COUNTFLAG bit to 0. +#define AM_REG_SYSTICK_SYSTCVR_CURRENT_S 0 +#define AM_REG_SYSTICK_SYSTCVR_CURRENT_M 0x00FFFFFF +#define AM_REG_SYSTICK_SYSTCVR_CURRENT(n) (((uint32_t)(n) << 0) & 0x00FFFFFF) + +//***************************************************************************** +// +// SYSTICK_SYSTCALIB - SysTick Calibration Value Register. +// +//***************************************************************************** +// Indicates whether the device provides a reference clock to the processor. 0 = +// reference clock provided; 1 = no reference clock provided. If your device +// does not provide a reference clock, the SYST_CSR.CLKSOURCE bit reads-as-one +// and ignores writes. +#define AM_REG_SYSTICK_SYSTCALIB_NOREF_S 31 +#define AM_REG_SYSTICK_SYSTCALIB_NOREF_M 0x80000000 +#define AM_REG_SYSTICK_SYSTCALIB_NOREF(n) (((uint32_t)(n) << 31) & 0x80000000) + +// Indicates whether the TENMS value is exact. 0 = TENMS value is exact; 1 = +// TENMS value is inexact, or not given. An inexact TENMS value can affect the +// suitability of SysTick as a software real time clock. +#define AM_REG_SYSTICK_SYSTCALIB_SKEW_S 30 +#define AM_REG_SYSTICK_SYSTCALIB_SKEW_M 0x40000000 +#define AM_REG_SYSTICK_SYSTCALIB_SKEW(n) (((uint32_t)(n) << 30) & 0x40000000) + +// Reload value for 10ms (100Hz) timing, subject to system clock skew errors. If +// the value reads as zero, the calibration value is not known. +#define AM_REG_SYSTICK_SYSTCALIB_TENMS_S 0 +#define AM_REG_SYSTICK_SYSTCALIB_TENMS_M 0x00FFFFFF +#define AM_REG_SYSTICK_SYSTCALIB_TENMS(n) (((uint32_t)(n) << 0) & 0x00FFFFFF) + +#endif // AM_REG_SYSTICK_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_tpiu.h b/bsp/apollo2/libraries/drivers/regs/am_reg_tpiu.h new file mode 100644 index 0000000000..e3719b60f8 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_tpiu.h @@ -0,0 +1,164 @@ +//***************************************************************************** +// +// am_reg_tpiu.h +//! @file +//! +//! @brief Register macros for the TPIU module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_TPIU_H +#define AM_REG_TPIU_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_TPIU_NUM_MODULES 1 +#define AM_REG_TPIUn(n) \ + (REG_TPIU_BASEADDR + 0x00000000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_TPIU_SSPSR_O 0xE0040000 +#define AM_REG_TPIU_CSPSR_O 0xE0040004 +#define AM_REG_TPIU_ACPR_O 0xE0040010 +#define AM_REG_TPIU_SPPR_O 0xE00400F0 +#define AM_REG_TPIU_FFCR_O 0xE0040304 +#define AM_REG_TPIU_ITCTRL_O 0xE0040F00 +#define AM_REG_TPIU_TYPE_O 0xE0040FC8 + +//***************************************************************************** +// +// TPIU_SSPSR - Supported Parallel Port Sizes. +// +//***************************************************************************** +// Parallel Port Width 1 supported +#define AM_REG_TPIU_SSPSR_SWIDTH0_S 0 +#define AM_REG_TPIU_SSPSR_SWIDTH0_M 0x00000001 +#define AM_REG_TPIU_SSPSR_SWIDTH0(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// TPIU_CSPSR - Current Parallel Port Size. +// +//***************************************************************************** +// One-hot representation of the current port width. +#define AM_REG_TPIU_CSPSR_CWIDTH_S 0 +#define AM_REG_TPIU_CSPSR_CWIDTH_M 0xFFFFFFFF +#define AM_REG_TPIU_CSPSR_CWIDTH(n) (((uint32_t)(n) << 0) & 0xFFFFFFFF) +#define AM_REG_TPIU_CSPSR_CWIDTH_1BIT 0x00000001 + +//***************************************************************************** +// +// TPIU_ACPR - Asynchronous Clock Prescaler. +// +//***************************************************************************** +// Prescaler value for the baudrate of SWO. +#define AM_REG_TPIU_ACPR_SWOSCALER_S 0 +#define AM_REG_TPIU_ACPR_SWOSCALER_M 0x0000FFFF +#define AM_REG_TPIU_ACPR_SWOSCALER(n) (((uint32_t)(n) << 0) & 0x0000FFFF) +#define AM_REG_TPIU_ACPR_SWOSCALER_115200 0x00000033 + +//***************************************************************************** +// +// TPIU_SPPR - Selected Pin Protocol. +// +//***************************************************************************** +// Selects the protocol used for trace output. +#define AM_REG_TPIU_SPPR_TXMODE_S 0 +#define AM_REG_TPIU_SPPR_TXMODE_M 0x00000003 +#define AM_REG_TPIU_SPPR_TXMODE(n) (((uint32_t)(n) << 0) & 0x00000003) +#define AM_REG_TPIU_SPPR_TXMODE_PARALLEL 0x00000000 +#define AM_REG_TPIU_SPPR_TXMODE_MANCHESTER 0x00000001 +#define AM_REG_TPIU_SPPR_TXMODE_NRZ 0x00000002 +#define AM_REG_TPIU_SPPR_TXMODE_UART 0x00000002 + +//***************************************************************************** +// +// TPIU_FFCR - Formatter and Flush Control Register. +// +//***************************************************************************** +// Enable continuous formatting. +#define AM_REG_TPIU_FFCR_ENFCONT_S 1 +#define AM_REG_TPIU_FFCR_ENFCONT_M 0x00000002 +#define AM_REG_TPIU_FFCR_ENFCONT(n) (((uint32_t)(n) << 1) & 0x00000002) + +//***************************************************************************** +// +// TPIU_ITCTRL - Specifies normal or integration mode for the TPIU. +// +//***************************************************************************** +// Specifies the current mode for the TPIU. +#define AM_REG_TPIU_ITCTRL_MODE_S 0 +#define AM_REG_TPIU_ITCTRL_MODE_M 0x00000003 +#define AM_REG_TPIU_ITCTRL_MODE(n) (((uint32_t)(n) << 0) & 0x00000003) +#define AM_REG_TPIU_ITCTRL_MODE_NORMAL 0x00000000 +#define AM_REG_TPIU_ITCTRL_MODE_TEST 0x00000001 +#define AM_REG_TPIU_ITCTRL_MODE_DATA_TEST 0x00000002 + +//***************************************************************************** +// +// TPIU_TYPE - TPIU Type. +// +//***************************************************************************** +// 1 Indicates UART/NRZ support. +#define AM_REG_TPIU_TYPE_NRZVALID_S 11 +#define AM_REG_TPIU_TYPE_NRZVALID_M 0x00000800 +#define AM_REG_TPIU_TYPE_NRZVALID(n) (((uint32_t)(n) << 11) & 0x00000800) + +// 1 Indicates Manchester support. +#define AM_REG_TPIU_TYPE_MANCVALID_S 10 +#define AM_REG_TPIU_TYPE_MANCVALID_M 0x00000400 +#define AM_REG_TPIU_TYPE_MANCVALID(n) (((uint32_t)(n) << 10) & 0x00000400) + +// 0 Indicates Parallel Trace support. +#define AM_REG_TPIU_TYPE_PTINVALID_S 9 +#define AM_REG_TPIU_TYPE_PTINVALID_M 0x00000200 +#define AM_REG_TPIU_TYPE_PTINVALID(n) (((uint32_t)(n) << 9) & 0x00000200) + +// FIFO Size reported as a power of two. For instance, 0x3 indicates a FIFO size +// of 8 bytes. +#define AM_REG_TPIU_TYPE_FIFOSZ_S 6 +#define AM_REG_TPIU_TYPE_FIFOSZ_M 0x000001C0 +#define AM_REG_TPIU_TYPE_FIFOSZ(n) (((uint32_t)(n) << 6) & 0x000001C0) + +#endif // AM_REG_TPIU_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_uart.h b/bsp/apollo2/libraries/drivers/regs/am_reg_uart.h new file mode 100644 index 0000000000..493a947630 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_uart.h @@ -0,0 +1,612 @@ +//***************************************************************************** +// +// am_reg_uart.h +//! @file +//! +//! @brief Register macros for the UART module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_UART_H +#define AM_REG_UART_H + +//***************************************************************************** +// +// Instance finder. (2 instance(s) available) +// +//***************************************************************************** +#define AM_REG_UART_NUM_MODULES 2 +#define AM_REG_UARTn(n) \ + (REG_UART_BASEADDR + 0x00001000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_UART_DR_O 0x00000000 +#define AM_REG_UART_RSR_O 0x00000004 +#define AM_REG_UART_FR_O 0x00000018 +#define AM_REG_UART_ILPR_O 0x00000020 +#define AM_REG_UART_IBRD_O 0x00000024 +#define AM_REG_UART_FBRD_O 0x00000028 +#define AM_REG_UART_LCRH_O 0x0000002C +#define AM_REG_UART_CR_O 0x00000030 +#define AM_REG_UART_IFLS_O 0x00000034 +#define AM_REG_UART_IER_O 0x00000038 +#define AM_REG_UART_IES_O 0x0000003C +#define AM_REG_UART_MIS_O 0x00000040 +#define AM_REG_UART_IEC_O 0x00000044 + +//***************************************************************************** +// +// UART_DR - UART Data Register +// +//***************************************************************************** +// This is the overrun error indicator. +#define AM_REG_UART_DR_OEDATA_S 11 +#define AM_REG_UART_DR_OEDATA_M 0x00000800 +#define AM_REG_UART_DR_OEDATA(n) (((uint32_t)(n) << 11) & 0x00000800) +#define AM_REG_UART_DR_OEDATA_NOERR 0x00000000 +#define AM_REG_UART_DR_OEDATA_ERR 0x00000800 + +// This is the break error indicator. +#define AM_REG_UART_DR_BEDATA_S 10 +#define AM_REG_UART_DR_BEDATA_M 0x00000400 +#define AM_REG_UART_DR_BEDATA(n) (((uint32_t)(n) << 10) & 0x00000400) +#define AM_REG_UART_DR_BEDATA_NOERR 0x00000000 +#define AM_REG_UART_DR_BEDATA_ERR 0x00000400 + +// This is the parity error indicator. +#define AM_REG_UART_DR_PEDATA_S 9 +#define AM_REG_UART_DR_PEDATA_M 0x00000200 +#define AM_REG_UART_DR_PEDATA(n) (((uint32_t)(n) << 9) & 0x00000200) +#define AM_REG_UART_DR_PEDATA_NOERR 0x00000000 +#define AM_REG_UART_DR_PEDATA_ERR 0x00000200 + +// This is the framing error indicator. +#define AM_REG_UART_DR_FEDATA_S 8 +#define AM_REG_UART_DR_FEDATA_M 0x00000100 +#define AM_REG_UART_DR_FEDATA(n) (((uint32_t)(n) << 8) & 0x00000100) +#define AM_REG_UART_DR_FEDATA_NOERR 0x00000000 +#define AM_REG_UART_DR_FEDATA_ERR 0x00000100 + +// This is the UART data port. +#define AM_REG_UART_DR_DATA_S 0 +#define AM_REG_UART_DR_DATA_M 0x000000FF +#define AM_REG_UART_DR_DATA(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// UART_RSR - UART Status Register +// +//***************************************************************************** +// This is the overrun error indicator. +#define AM_REG_UART_RSR_OESTAT_S 3 +#define AM_REG_UART_RSR_OESTAT_M 0x00000008 +#define AM_REG_UART_RSR_OESTAT(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_UART_RSR_OESTAT_NOERR 0x00000000 +#define AM_REG_UART_RSR_OESTAT_ERR 0x00000008 + +// This is the break error indicator. +#define AM_REG_UART_RSR_BESTAT_S 2 +#define AM_REG_UART_RSR_BESTAT_M 0x00000004 +#define AM_REG_UART_RSR_BESTAT(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_UART_RSR_BESTAT_NOERR 0x00000000 +#define AM_REG_UART_RSR_BESTAT_ERR 0x00000004 + +// This is the parity error indicator. +#define AM_REG_UART_RSR_PESTAT_S 1 +#define AM_REG_UART_RSR_PESTAT_M 0x00000002 +#define AM_REG_UART_RSR_PESTAT(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_UART_RSR_PESTAT_NOERR 0x00000000 +#define AM_REG_UART_RSR_PESTAT_ERR 0x00000002 + +// This is the framing error indicator. +#define AM_REG_UART_RSR_FESTAT_S 0 +#define AM_REG_UART_RSR_FESTAT_M 0x00000001 +#define AM_REG_UART_RSR_FESTAT(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_UART_RSR_FESTAT_NOERR 0x00000000 +#define AM_REG_UART_RSR_FESTAT_ERR 0x00000001 + +//***************************************************************************** +// +// UART_FR - Flag Register +// +//***************************************************************************** +// This bit holds the transmit BUSY indicator. +#define AM_REG_UART_FR_TXBUSY_S 8 +#define AM_REG_UART_FR_TXBUSY_M 0x00000100 +#define AM_REG_UART_FR_TXBUSY(n) (((uint32_t)(n) << 8) & 0x00000100) + +// This bit holds the transmit FIFO empty indicator. +#define AM_REG_UART_FR_TXFE_S 7 +#define AM_REG_UART_FR_TXFE_M 0x00000080 +#define AM_REG_UART_FR_TXFE(n) (((uint32_t)(n) << 7) & 0x00000080) +#define AM_REG_UART_FR_TXFE_XMTFIFO_EMPTY 0x00000080 + +// This bit holds the receive FIFO full indicator. +#define AM_REG_UART_FR_RXFF_S 6 +#define AM_REG_UART_FR_RXFF_M 0x00000040 +#define AM_REG_UART_FR_RXFF(n) (((uint32_t)(n) << 6) & 0x00000040) +#define AM_REG_UART_FR_RXFF_RCVFIFO_FULL 0x00000040 + +// This bit holds the transmit FIFO full indicator. +#define AM_REG_UART_FR_TXFF_S 5 +#define AM_REG_UART_FR_TXFF_M 0x00000020 +#define AM_REG_UART_FR_TXFF(n) (((uint32_t)(n) << 5) & 0x00000020) +#define AM_REG_UART_FR_TXFF_XMTFIFO_FULL 0x00000020 + +// This bit holds the receive FIFO empty indicator. +#define AM_REG_UART_FR_RXFE_S 4 +#define AM_REG_UART_FR_RXFE_M 0x00000010 +#define AM_REG_UART_FR_RXFE(n) (((uint32_t)(n) << 4) & 0x00000010) +#define AM_REG_UART_FR_RXFE_RCVFIFO_EMPTY 0x00000010 + +// This bit holds the busy indicator. +#define AM_REG_UART_FR_BUSY_S 3 +#define AM_REG_UART_FR_BUSY_M 0x00000008 +#define AM_REG_UART_FR_BUSY(n) (((uint32_t)(n) << 3) & 0x00000008) +#define AM_REG_UART_FR_BUSY_BUSY 0x00000008 + +// This bit holds the data carrier detect indicator. +#define AM_REG_UART_FR_DCD_S 2 +#define AM_REG_UART_FR_DCD_M 0x00000004 +#define AM_REG_UART_FR_DCD(n) (((uint32_t)(n) << 2) & 0x00000004) +#define AM_REG_UART_FR_DCD_DETECTED 0x00000004 + +// This bit holds the data set ready indicator. +#define AM_REG_UART_FR_DSR_S 1 +#define AM_REG_UART_FR_DSR_M 0x00000002 +#define AM_REG_UART_FR_DSR(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_UART_FR_DSR_READY 0x00000002 + +// This bit holds the clear to send indicator. +#define AM_REG_UART_FR_CTS_S 0 +#define AM_REG_UART_FR_CTS_M 0x00000001 +#define AM_REG_UART_FR_CTS(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_UART_FR_CTS_CLEARTOSEND 0x00000001 + +//***************************************************************************** +// +// UART_ILPR - IrDA Counter +// +//***************************************************************************** +// These bits hold the IrDA counter divisor. +#define AM_REG_UART_ILPR_ILPDVSR_S 0 +#define AM_REG_UART_ILPR_ILPDVSR_M 0x000000FF +#define AM_REG_UART_ILPR_ILPDVSR(n) (((uint32_t)(n) << 0) & 0x000000FF) + +//***************************************************************************** +// +// UART_IBRD - Integer Baud Rate Divisor +// +//***************************************************************************** +// These bits hold the baud integer divisor. +#define AM_REG_UART_IBRD_DIVINT_S 0 +#define AM_REG_UART_IBRD_DIVINT_M 0x0000FFFF +#define AM_REG_UART_IBRD_DIVINT(n) (((uint32_t)(n) << 0) & 0x0000FFFF) + +//***************************************************************************** +// +// UART_FBRD - Fractional Baud Rate Divisor +// +//***************************************************************************** +// These bits hold the baud fractional divisor. +#define AM_REG_UART_FBRD_DIVFRAC_S 0 +#define AM_REG_UART_FBRD_DIVFRAC_M 0x0000003F +#define AM_REG_UART_FBRD_DIVFRAC(n) (((uint32_t)(n) << 0) & 0x0000003F) + +//***************************************************************************** +// +// UART_LCRH - Line Control High +// +//***************************************************************************** +// This bit holds the stick parity select. +#define AM_REG_UART_LCRH_SPS_S 7 +#define AM_REG_UART_LCRH_SPS_M 0x00000080 +#define AM_REG_UART_LCRH_SPS(n) (((uint32_t)(n) << 7) & 0x00000080) + +// These bits hold the write length. +#define AM_REG_UART_LCRH_WLEN_S 5 +#define AM_REG_UART_LCRH_WLEN_M 0x00000060 +#define AM_REG_UART_LCRH_WLEN(n) (((uint32_t)(n) << 5) & 0x00000060) + +// This bit holds the FIFO enable. +#define AM_REG_UART_LCRH_FEN_S 4 +#define AM_REG_UART_LCRH_FEN_M 0x00000010 +#define AM_REG_UART_LCRH_FEN(n) (((uint32_t)(n) << 4) & 0x00000010) + +// This bit holds the two stop bits select. +#define AM_REG_UART_LCRH_STP2_S 3 +#define AM_REG_UART_LCRH_STP2_M 0x00000008 +#define AM_REG_UART_LCRH_STP2(n) (((uint32_t)(n) << 3) & 0x00000008) + +// This bit holds the even parity select. +#define AM_REG_UART_LCRH_EPS_S 2 +#define AM_REG_UART_LCRH_EPS_M 0x00000004 +#define AM_REG_UART_LCRH_EPS(n) (((uint32_t)(n) << 2) & 0x00000004) + +// This bit holds the parity enable. +#define AM_REG_UART_LCRH_PEN_S 1 +#define AM_REG_UART_LCRH_PEN_M 0x00000002 +#define AM_REG_UART_LCRH_PEN(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This bit holds the break set. +#define AM_REG_UART_LCRH_BRK_S 0 +#define AM_REG_UART_LCRH_BRK_M 0x00000001 +#define AM_REG_UART_LCRH_BRK(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// UART_CR - Control Register +// +//***************************************************************************** +// This bit enables CTS hardware flow control. +#define AM_REG_UART_CR_CTSEN_S 15 +#define AM_REG_UART_CR_CTSEN_M 0x00008000 +#define AM_REG_UART_CR_CTSEN(n) (((uint32_t)(n) << 15) & 0x00008000) + +// This bit enables RTS hardware flow control. +#define AM_REG_UART_CR_RTSEN_S 14 +#define AM_REG_UART_CR_RTSEN_M 0x00004000 +#define AM_REG_UART_CR_RTSEN(n) (((uint32_t)(n) << 14) & 0x00004000) + +// This bit holds modem Out2. +#define AM_REG_UART_CR_OUT2_S 13 +#define AM_REG_UART_CR_OUT2_M 0x00002000 +#define AM_REG_UART_CR_OUT2(n) (((uint32_t)(n) << 13) & 0x00002000) + +// This bit holds modem Out1. +#define AM_REG_UART_CR_OUT1_S 12 +#define AM_REG_UART_CR_OUT1_M 0x00001000 +#define AM_REG_UART_CR_OUT1(n) (((uint32_t)(n) << 12) & 0x00001000) + +// This bit enables request to send. +#define AM_REG_UART_CR_RTS_S 11 +#define AM_REG_UART_CR_RTS_M 0x00000800 +#define AM_REG_UART_CR_RTS(n) (((uint32_t)(n) << 11) & 0x00000800) + +// This bit enables data transmit ready. +#define AM_REG_UART_CR_DTR_S 10 +#define AM_REG_UART_CR_DTR_M 0x00000400 +#define AM_REG_UART_CR_DTR(n) (((uint32_t)(n) << 10) & 0x00000400) + +// This bit is the receive enable. +#define AM_REG_UART_CR_RXE_S 9 +#define AM_REG_UART_CR_RXE_M 0x00000200 +#define AM_REG_UART_CR_RXE(n) (((uint32_t)(n) << 9) & 0x00000200) + +// This bit is the transmit enable. +#define AM_REG_UART_CR_TXE_S 8 +#define AM_REG_UART_CR_TXE_M 0x00000100 +#define AM_REG_UART_CR_TXE(n) (((uint32_t)(n) << 8) & 0x00000100) + +// This bit is the loopback enable. +#define AM_REG_UART_CR_LBE_S 7 +#define AM_REG_UART_CR_LBE_M 0x00000080 +#define AM_REG_UART_CR_LBE(n) (((uint32_t)(n) << 7) & 0x00000080) + +// This bitfield is the UART clock select. +#define AM_REG_UART_CR_CLKSEL_S 4 +#define AM_REG_UART_CR_CLKSEL_M 0x00000070 +#define AM_REG_UART_CR_CLKSEL(n) (((uint32_t)(n) << 4) & 0x00000070) +#define AM_REG_UART_CR_CLKSEL_NOCLK 0x00000000 +#define AM_REG_UART_CR_CLKSEL_24MHZ 0x00000010 +#define AM_REG_UART_CR_CLKSEL_12MHZ 0x00000020 +#define AM_REG_UART_CR_CLKSEL_6MHZ 0x00000030 +#define AM_REG_UART_CR_CLKSEL_3MHZ 0x00000040 +#define AM_REG_UART_CR_CLKSEL_RSVD5 0x00000050 +#define AM_REG_UART_CR_CLKSEL_RSVD6 0x00000060 +#define AM_REG_UART_CR_CLKSEL_RSVD7 0x00000070 + +// This bit is the UART clock enable. +#define AM_REG_UART_CR_CLKEN_S 3 +#define AM_REG_UART_CR_CLKEN_M 0x00000008 +#define AM_REG_UART_CR_CLKEN(n) (((uint32_t)(n) << 3) & 0x00000008) + +// This bit is the SIR low power select. +#define AM_REG_UART_CR_SIRLP_S 2 +#define AM_REG_UART_CR_SIRLP_M 0x00000004 +#define AM_REG_UART_CR_SIRLP(n) (((uint32_t)(n) << 2) & 0x00000004) + +// This bit is the SIR ENDEC enable. +#define AM_REG_UART_CR_SIREN_S 1 +#define AM_REG_UART_CR_SIREN_M 0x00000002 +#define AM_REG_UART_CR_SIREN(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This bit is the UART enable. +#define AM_REG_UART_CR_UARTEN_S 0 +#define AM_REG_UART_CR_UARTEN_M 0x00000001 +#define AM_REG_UART_CR_UARTEN(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// UART_IFLS - FIFO Interrupt Level Select +// +//***************************************************************************** +// These bits hold the receive FIFO interrupt level. +#define AM_REG_UART_IFLS_RXIFLSEL_S 3 +#define AM_REG_UART_IFLS_RXIFLSEL_M 0x00000038 +#define AM_REG_UART_IFLS_RXIFLSEL(n) (((uint32_t)(n) << 3) & 0x00000038) + +// These bits hold the transmit FIFO interrupt level. +#define AM_REG_UART_IFLS_TXIFLSEL_S 0 +#define AM_REG_UART_IFLS_TXIFLSEL_M 0x00000007 +#define AM_REG_UART_IFLS_TXIFLSEL(n) (((uint32_t)(n) << 0) & 0x00000007) + +//***************************************************************************** +// +// UART_IER - Interrupt Enable +// +//***************************************************************************** +// This bit holds the overflow interrupt enable. +#define AM_REG_UART_IER_OEIM_S 10 +#define AM_REG_UART_IER_OEIM_M 0x00000400 +#define AM_REG_UART_IER_OEIM(n) (((uint32_t)(n) << 10) & 0x00000400) + +// This bit holds the break error interrupt enable. +#define AM_REG_UART_IER_BEIM_S 9 +#define AM_REG_UART_IER_BEIM_M 0x00000200 +#define AM_REG_UART_IER_BEIM(n) (((uint32_t)(n) << 9) & 0x00000200) + +// This bit holds the parity error interrupt enable. +#define AM_REG_UART_IER_PEIM_S 8 +#define AM_REG_UART_IER_PEIM_M 0x00000100 +#define AM_REG_UART_IER_PEIM(n) (((uint32_t)(n) << 8) & 0x00000100) + +// This bit holds the framing error interrupt enable. +#define AM_REG_UART_IER_FEIM_S 7 +#define AM_REG_UART_IER_FEIM_M 0x00000080 +#define AM_REG_UART_IER_FEIM(n) (((uint32_t)(n) << 7) & 0x00000080) + +// This bit holds the receive timeout interrupt enable. +#define AM_REG_UART_IER_RTIM_S 6 +#define AM_REG_UART_IER_RTIM_M 0x00000040 +#define AM_REG_UART_IER_RTIM(n) (((uint32_t)(n) << 6) & 0x00000040) + +// This bit holds the transmit interrupt enable. +#define AM_REG_UART_IER_TXIM_S 5 +#define AM_REG_UART_IER_TXIM_M 0x00000020 +#define AM_REG_UART_IER_TXIM(n) (((uint32_t)(n) << 5) & 0x00000020) + +// This bit holds the receive interrupt enable. +#define AM_REG_UART_IER_RXIM_S 4 +#define AM_REG_UART_IER_RXIM_M 0x00000010 +#define AM_REG_UART_IER_RXIM(n) (((uint32_t)(n) << 4) & 0x00000010) + +// This bit holds the modem DSR interrupt enable. +#define AM_REG_UART_IER_DSRMIM_S 3 +#define AM_REG_UART_IER_DSRMIM_M 0x00000008 +#define AM_REG_UART_IER_DSRMIM(n) (((uint32_t)(n) << 3) & 0x00000008) + +// This bit holds the modem DCD interrupt enable. +#define AM_REG_UART_IER_DCDMIM_S 2 +#define AM_REG_UART_IER_DCDMIM_M 0x00000004 +#define AM_REG_UART_IER_DCDMIM(n) (((uint32_t)(n) << 2) & 0x00000004) + +// This bit holds the modem CTS interrupt enable. +#define AM_REG_UART_IER_CTSMIM_S 1 +#define AM_REG_UART_IER_CTSMIM_M 0x00000002 +#define AM_REG_UART_IER_CTSMIM(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This bit holds the modem TXCMP interrupt enable. +#define AM_REG_UART_IER_TXCMPMIM_S 0 +#define AM_REG_UART_IER_TXCMPMIM_M 0x00000001 +#define AM_REG_UART_IER_TXCMPMIM(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// UART_IES - Interrupt Status +// +//***************************************************************************** +// This bit holds the overflow interrupt status. +#define AM_REG_UART_IES_OERIS_S 10 +#define AM_REG_UART_IES_OERIS_M 0x00000400 +#define AM_REG_UART_IES_OERIS(n) (((uint32_t)(n) << 10) & 0x00000400) + +// This bit holds the break error interrupt status. +#define AM_REG_UART_IES_BERIS_S 9 +#define AM_REG_UART_IES_BERIS_M 0x00000200 +#define AM_REG_UART_IES_BERIS(n) (((uint32_t)(n) << 9) & 0x00000200) + +// This bit holds the parity error interrupt status. +#define AM_REG_UART_IES_PERIS_S 8 +#define AM_REG_UART_IES_PERIS_M 0x00000100 +#define AM_REG_UART_IES_PERIS(n) (((uint32_t)(n) << 8) & 0x00000100) + +// This bit holds the framing error interrupt status. +#define AM_REG_UART_IES_FERIS_S 7 +#define AM_REG_UART_IES_FERIS_M 0x00000080 +#define AM_REG_UART_IES_FERIS(n) (((uint32_t)(n) << 7) & 0x00000080) + +// This bit holds the receive timeout interrupt status. +#define AM_REG_UART_IES_RTRIS_S 6 +#define AM_REG_UART_IES_RTRIS_M 0x00000040 +#define AM_REG_UART_IES_RTRIS(n) (((uint32_t)(n) << 6) & 0x00000040) + +// This bit holds the transmit interrupt status. +#define AM_REG_UART_IES_TXRIS_S 5 +#define AM_REG_UART_IES_TXRIS_M 0x00000020 +#define AM_REG_UART_IES_TXRIS(n) (((uint32_t)(n) << 5) & 0x00000020) + +// This bit holds the receive interrupt status. +#define AM_REG_UART_IES_RXRIS_S 4 +#define AM_REG_UART_IES_RXRIS_M 0x00000010 +#define AM_REG_UART_IES_RXRIS(n) (((uint32_t)(n) << 4) & 0x00000010) + +// This bit holds the modem DSR interrupt status. +#define AM_REG_UART_IES_DSRMRIS_S 3 +#define AM_REG_UART_IES_DSRMRIS_M 0x00000008 +#define AM_REG_UART_IES_DSRMRIS(n) (((uint32_t)(n) << 3) & 0x00000008) + +// This bit holds the modem DCD interrupt status. +#define AM_REG_UART_IES_DCDMRIS_S 2 +#define AM_REG_UART_IES_DCDMRIS_M 0x00000004 +#define AM_REG_UART_IES_DCDMRIS(n) (((uint32_t)(n) << 2) & 0x00000004) + +// This bit holds the modem CTS interrupt status. +#define AM_REG_UART_IES_CTSMRIS_S 1 +#define AM_REG_UART_IES_CTSMRIS_M 0x00000002 +#define AM_REG_UART_IES_CTSMRIS(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This bit holds the modem TXCMP interrupt status. +#define AM_REG_UART_IES_TXCMPMRIS_S 0 +#define AM_REG_UART_IES_TXCMPMRIS_M 0x00000001 +#define AM_REG_UART_IES_TXCMPMRIS(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// UART_MIS - Masked Interrupt Status +// +//***************************************************************************** +// This bit holds the overflow interrupt status masked. +#define AM_REG_UART_MIS_OEMIS_S 10 +#define AM_REG_UART_MIS_OEMIS_M 0x00000400 +#define AM_REG_UART_MIS_OEMIS(n) (((uint32_t)(n) << 10) & 0x00000400) + +// This bit holds the break error interrupt status masked. +#define AM_REG_UART_MIS_BEMIS_S 9 +#define AM_REG_UART_MIS_BEMIS_M 0x00000200 +#define AM_REG_UART_MIS_BEMIS(n) (((uint32_t)(n) << 9) & 0x00000200) + +// This bit holds the parity error interrupt status masked. +#define AM_REG_UART_MIS_PEMIS_S 8 +#define AM_REG_UART_MIS_PEMIS_M 0x00000100 +#define AM_REG_UART_MIS_PEMIS(n) (((uint32_t)(n) << 8) & 0x00000100) + +// This bit holds the framing error interrupt status masked. +#define AM_REG_UART_MIS_FEMIS_S 7 +#define AM_REG_UART_MIS_FEMIS_M 0x00000080 +#define AM_REG_UART_MIS_FEMIS(n) (((uint32_t)(n) << 7) & 0x00000080) + +// This bit holds the receive timeout interrupt status masked. +#define AM_REG_UART_MIS_RTMIS_S 6 +#define AM_REG_UART_MIS_RTMIS_M 0x00000040 +#define AM_REG_UART_MIS_RTMIS(n) (((uint32_t)(n) << 6) & 0x00000040) + +// This bit holds the transmit interrupt status masked. +#define AM_REG_UART_MIS_TXMIS_S 5 +#define AM_REG_UART_MIS_TXMIS_M 0x00000020 +#define AM_REG_UART_MIS_TXMIS(n) (((uint32_t)(n) << 5) & 0x00000020) + +// This bit holds the receive interrupt status masked. +#define AM_REG_UART_MIS_RXMIS_S 4 +#define AM_REG_UART_MIS_RXMIS_M 0x00000010 +#define AM_REG_UART_MIS_RXMIS(n) (((uint32_t)(n) << 4) & 0x00000010) + +// This bit holds the modem DSR interrupt status masked. +#define AM_REG_UART_MIS_DSRMMIS_S 3 +#define AM_REG_UART_MIS_DSRMMIS_M 0x00000008 +#define AM_REG_UART_MIS_DSRMMIS(n) (((uint32_t)(n) << 3) & 0x00000008) + +// This bit holds the modem DCD interrupt status masked. +#define AM_REG_UART_MIS_DCDMMIS_S 2 +#define AM_REG_UART_MIS_DCDMMIS_M 0x00000004 +#define AM_REG_UART_MIS_DCDMMIS(n) (((uint32_t)(n) << 2) & 0x00000004) + +// This bit holds the modem CTS interrupt status masked. +#define AM_REG_UART_MIS_CTSMMIS_S 1 +#define AM_REG_UART_MIS_CTSMMIS_M 0x00000002 +#define AM_REG_UART_MIS_CTSMMIS(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This bit holds the modem TXCMP interrupt status masked. +#define AM_REG_UART_MIS_TXCMPMMIS_S 0 +#define AM_REG_UART_MIS_TXCMPMMIS_M 0x00000001 +#define AM_REG_UART_MIS_TXCMPMMIS(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// UART_IEC - Interrupt Clear +// +//***************************************************************************** +// This bit holds the overflow interrupt clear. +#define AM_REG_UART_IEC_OEIC_S 10 +#define AM_REG_UART_IEC_OEIC_M 0x00000400 +#define AM_REG_UART_IEC_OEIC(n) (((uint32_t)(n) << 10) & 0x00000400) + +// This bit holds the break error interrupt clear. +#define AM_REG_UART_IEC_BEIC_S 9 +#define AM_REG_UART_IEC_BEIC_M 0x00000200 +#define AM_REG_UART_IEC_BEIC(n) (((uint32_t)(n) << 9) & 0x00000200) + +// This bit holds the parity error interrupt clear. +#define AM_REG_UART_IEC_PEIC_S 8 +#define AM_REG_UART_IEC_PEIC_M 0x00000100 +#define AM_REG_UART_IEC_PEIC(n) (((uint32_t)(n) << 8) & 0x00000100) + +// This bit holds the framing error interrupt clear. +#define AM_REG_UART_IEC_FEIC_S 7 +#define AM_REG_UART_IEC_FEIC_M 0x00000080 +#define AM_REG_UART_IEC_FEIC(n) (((uint32_t)(n) << 7) & 0x00000080) + +// This bit holds the receive timeout interrupt clear. +#define AM_REG_UART_IEC_RTIC_S 6 +#define AM_REG_UART_IEC_RTIC_M 0x00000040 +#define AM_REG_UART_IEC_RTIC(n) (((uint32_t)(n) << 6) & 0x00000040) + +// This bit holds the transmit interrupt clear. +#define AM_REG_UART_IEC_TXIC_S 5 +#define AM_REG_UART_IEC_TXIC_M 0x00000020 +#define AM_REG_UART_IEC_TXIC(n) (((uint32_t)(n) << 5) & 0x00000020) + +// This bit holds the receive interrupt clear. +#define AM_REG_UART_IEC_RXIC_S 4 +#define AM_REG_UART_IEC_RXIC_M 0x00000010 +#define AM_REG_UART_IEC_RXIC(n) (((uint32_t)(n) << 4) & 0x00000010) + +// This bit holds the modem DSR interrupt clear. +#define AM_REG_UART_IEC_DSRMIC_S 3 +#define AM_REG_UART_IEC_DSRMIC_M 0x00000008 +#define AM_REG_UART_IEC_DSRMIC(n) (((uint32_t)(n) << 3) & 0x00000008) + +// This bit holds the modem DCD interrupt clear. +#define AM_REG_UART_IEC_DCDMIC_S 2 +#define AM_REG_UART_IEC_DCDMIC_M 0x00000004 +#define AM_REG_UART_IEC_DCDMIC(n) (((uint32_t)(n) << 2) & 0x00000004) + +// This bit holds the modem CTS interrupt clear. +#define AM_REG_UART_IEC_CTSMIC_S 1 +#define AM_REG_UART_IEC_CTSMIC_M 0x00000002 +#define AM_REG_UART_IEC_CTSMIC(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This bit holds the modem TXCMP interrupt clear. +#define AM_REG_UART_IEC_TXCMPMIC_S 0 +#define AM_REG_UART_IEC_TXCMPMIC_M 0x00000001 +#define AM_REG_UART_IEC_TXCMPMIC(n) (((uint32_t)(n) << 0) & 0x00000001) + +#endif // AM_REG_UART_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_vcomp.h b/bsp/apollo2/libraries/drivers/regs/am_reg_vcomp.h new file mode 100644 index 0000000000..93c610e123 --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_vcomp.h @@ -0,0 +1,200 @@ +//***************************************************************************** +// +// am_reg_vcomp.h +//! @file +//! +//! @brief Register macros for the VCOMP module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_VCOMP_H +#define AM_REG_VCOMP_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_VCOMP_NUM_MODULES 1 +#define AM_REG_VCOMPn(n) \ + (REG_VCOMP_BASEADDR + 0x00000000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_VCOMP_CFG_O 0x00000000 +#define AM_REG_VCOMP_STAT_O 0x00000004 +#define AM_REG_VCOMP_PWDKEY_O 0x00000008 +#define AM_REG_VCOMP_INTEN_O 0x00000200 +#define AM_REG_VCOMP_INTSTAT_O 0x00000204 +#define AM_REG_VCOMP_INTCLR_O 0x00000208 +#define AM_REG_VCOMP_INTSET_O 0x0000020C + +//***************************************************************************** +// +// Key values. +// +//***************************************************************************** +#define AM_REG_VCOMP_PWDKEY_KEYVAL 0x00000037 + +//***************************************************************************** +// +// VCOMP_INTEN - Voltage Comparator Interrupt registers: Enable +// +//***************************************************************************** +// This bit is the vcompout high interrupt. +#define AM_REG_VCOMP_INTEN_OUTHI_S 1 +#define AM_REG_VCOMP_INTEN_OUTHI_M 0x00000002 +#define AM_REG_VCOMP_INTEN_OUTHI(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This bit is the vcompout low interrupt. +#define AM_REG_VCOMP_INTEN_OUTLOW_S 0 +#define AM_REG_VCOMP_INTEN_OUTLOW_M 0x00000001 +#define AM_REG_VCOMP_INTEN_OUTLOW(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// VCOMP_INTSTAT - Voltage Comparator Interrupt registers: Status +// +//***************************************************************************** +// This bit is the vcompout high interrupt. +#define AM_REG_VCOMP_INTSTAT_OUTHI_S 1 +#define AM_REG_VCOMP_INTSTAT_OUTHI_M 0x00000002 +#define AM_REG_VCOMP_INTSTAT_OUTHI(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This bit is the vcompout low interrupt. +#define AM_REG_VCOMP_INTSTAT_OUTLOW_S 0 +#define AM_REG_VCOMP_INTSTAT_OUTLOW_M 0x00000001 +#define AM_REG_VCOMP_INTSTAT_OUTLOW(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// VCOMP_INTCLR - Voltage Comparator Interrupt registers: Clear +// +//***************************************************************************** +// This bit is the vcompout high interrupt. +#define AM_REG_VCOMP_INTCLR_OUTHI_S 1 +#define AM_REG_VCOMP_INTCLR_OUTHI_M 0x00000002 +#define AM_REG_VCOMP_INTCLR_OUTHI(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This bit is the vcompout low interrupt. +#define AM_REG_VCOMP_INTCLR_OUTLOW_S 0 +#define AM_REG_VCOMP_INTCLR_OUTLOW_M 0x00000001 +#define AM_REG_VCOMP_INTCLR_OUTLOW(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// VCOMP_INTSET - Voltage Comparator Interrupt registers: Set +// +//***************************************************************************** +// This bit is the vcompout high interrupt. +#define AM_REG_VCOMP_INTSET_OUTHI_S 1 +#define AM_REG_VCOMP_INTSET_OUTHI_M 0x00000002 +#define AM_REG_VCOMP_INTSET_OUTHI(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This bit is the vcompout low interrupt. +#define AM_REG_VCOMP_INTSET_OUTLOW_S 0 +#define AM_REG_VCOMP_INTSET_OUTLOW_M 0x00000001 +#define AM_REG_VCOMP_INTSET_OUTLOW(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// VCOMP_CFG - Configuration Register +// +//***************************************************************************** +// When the reference input NSEL is set to NSEL_DAC, this bitfield selects the +// voltage level for the negative input to the comparator. +#define AM_REG_VCOMP_CFG_LVLSEL_S 16 +#define AM_REG_VCOMP_CFG_LVLSEL_M 0x000F0000 +#define AM_REG_VCOMP_CFG_LVLSEL(n) (((uint32_t)(n) << 16) & 0x000F0000) +#define AM_REG_VCOMP_CFG_LVLSEL_0P58V 0x00000000 +#define AM_REG_VCOMP_CFG_LVLSEL_0P77V 0x00010000 +#define AM_REG_VCOMP_CFG_LVLSEL_0P97V 0x00020000 +#define AM_REG_VCOMP_CFG_LVLSEL_1P16V 0x00030000 +#define AM_REG_VCOMP_CFG_LVLSEL_1P35V 0x00040000 +#define AM_REG_VCOMP_CFG_LVLSEL_1P55V 0x00050000 +#define AM_REG_VCOMP_CFG_LVLSEL_1P74V 0x00060000 +#define AM_REG_VCOMP_CFG_LVLSEL_1P93V 0x00070000 +#define AM_REG_VCOMP_CFG_LVLSEL_2P13V 0x00080000 +#define AM_REG_VCOMP_CFG_LVLSEL_2P32V 0x00090000 +#define AM_REG_VCOMP_CFG_LVLSEL_2P51V 0x000A0000 +#define AM_REG_VCOMP_CFG_LVLSEL_2P71V 0x000B0000 +#define AM_REG_VCOMP_CFG_LVLSEL_2P90V 0x000C0000 +#define AM_REG_VCOMP_CFG_LVLSEL_3P09V 0x000D0000 +#define AM_REG_VCOMP_CFG_LVLSEL_3P29V 0x000E0000 +#define AM_REG_VCOMP_CFG_LVLSEL_3P48V 0x000F0000 + +// This bitfield selects the negative input to the comparator. +#define AM_REG_VCOMP_CFG_NSEL_S 8 +#define AM_REG_VCOMP_CFG_NSEL_M 0x00000300 +#define AM_REG_VCOMP_CFG_NSEL(n) (((uint32_t)(n) << 8) & 0x00000300) +#define AM_REG_VCOMP_CFG_NSEL_VREFEXT1 0x00000000 +#define AM_REG_VCOMP_CFG_NSEL_VREFEXT2 0x00000100 +#define AM_REG_VCOMP_CFG_NSEL_VREFEXT3 0x00000200 +#define AM_REG_VCOMP_CFG_NSEL_DAC 0x00000300 + +// This bitfield selects the positive input to the comparator. +#define AM_REG_VCOMP_CFG_PSEL_S 0 +#define AM_REG_VCOMP_CFG_PSEL_M 0x00000003 +#define AM_REG_VCOMP_CFG_PSEL(n) (((uint32_t)(n) << 0) & 0x00000003) +#define AM_REG_VCOMP_CFG_PSEL_VDDADJ 0x00000000 +#define AM_REG_VCOMP_CFG_PSEL_VTEMP 0x00000001 +#define AM_REG_VCOMP_CFG_PSEL_VEXT1 0x00000002 +#define AM_REG_VCOMP_CFG_PSEL_VEXT2 0x00000003 + +//***************************************************************************** +// +// VCOMP_STAT - Status Register +// +//***************************************************************************** +// This bit indicates the power down state of the voltage comparator. +#define AM_REG_VCOMP_STAT_PWDSTAT_S 1 +#define AM_REG_VCOMP_STAT_PWDSTAT_M 0x00000002 +#define AM_REG_VCOMP_STAT_PWDSTAT(n) (((uint32_t)(n) << 1) & 0x00000002) +#define AM_REG_VCOMP_STAT_PWDSTAT_POWERED_DOWN 0x00000002 + +// This bit is 1 if the positive input of the comparator is greater than the +// negative input. +#define AM_REG_VCOMP_STAT_CMPOUT_S 0 +#define AM_REG_VCOMP_STAT_CMPOUT_M 0x00000001 +#define AM_REG_VCOMP_STAT_CMPOUT(n) (((uint32_t)(n) << 0) & 0x00000001) +#define AM_REG_VCOMP_STAT_CMPOUT_VOUT_LOW 0x00000000 +#define AM_REG_VCOMP_STAT_CMPOUT_VOUT_HIGH 0x00000001 + +#endif // AM_REG_VCOMP_H diff --git a/bsp/apollo2/libraries/drivers/regs/am_reg_wdt.h b/bsp/apollo2/libraries/drivers/regs/am_reg_wdt.h new file mode 100644 index 0000000000..f95ddc1e8d --- /dev/null +++ b/bsp/apollo2/libraries/drivers/regs/am_reg_wdt.h @@ -0,0 +1,189 @@ +//***************************************************************************** +// +// am_reg_wdt.h +//! @file +//! +//! @brief Register macros for the WDT module +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** +#ifndef AM_REG_WDT_H +#define AM_REG_WDT_H + +//***************************************************************************** +// +// Instance finder. (1 instance(s) available) +// +//***************************************************************************** +#define AM_REG_WDT_NUM_MODULES 1 +#define AM_REG_WDTn(n) \ + (REG_WDT_BASEADDR + 0x00000000 * n) + +//***************************************************************************** +// +// Register offsets. +// +//***************************************************************************** +#define AM_REG_WDT_CFG_O 0x00000000 +#define AM_REG_WDT_RSTRT_O 0x00000004 +#define AM_REG_WDT_LOCK_O 0x00000008 +#define AM_REG_WDT_COUNT_O 0x0000000C +#define AM_REG_WDT_INTEN_O 0x00000200 +#define AM_REG_WDT_INTSTAT_O 0x00000204 +#define AM_REG_WDT_INTCLR_O 0x00000208 +#define AM_REG_WDT_INTSET_O 0x0000020C + +//***************************************************************************** +// +// WDT_INTEN - WDT Interrupt register: Enable +// +//***************************************************************************** +// Watchdog Timer Interrupt. +#define AM_REG_WDT_INTEN_WDT_S 0 +#define AM_REG_WDT_INTEN_WDT_M 0x00000001 +#define AM_REG_WDT_INTEN_WDT(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// WDT_INTSTAT - WDT Interrupt register: Status +// +//***************************************************************************** +// Watchdog Timer Interrupt. +#define AM_REG_WDT_INTSTAT_WDT_S 0 +#define AM_REG_WDT_INTSTAT_WDT_M 0x00000001 +#define AM_REG_WDT_INTSTAT_WDT(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// WDT_INTCLR - WDT Interrupt register: Clear +// +//***************************************************************************** +// Watchdog Timer Interrupt. +#define AM_REG_WDT_INTCLR_WDT_S 0 +#define AM_REG_WDT_INTCLR_WDT_M 0x00000001 +#define AM_REG_WDT_INTCLR_WDT(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// WDT_INTSET - WDT Interrupt register: Set +// +//***************************************************************************** +// Watchdog Timer Interrupt. +#define AM_REG_WDT_INTSET_WDT_S 0 +#define AM_REG_WDT_INTSET_WDT_M 0x00000001 +#define AM_REG_WDT_INTSET_WDT(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// WDT_CFG - Configuration Register +// +//***************************************************************************** +// Select the frequency for the WDT. All values not enumerated below are +// undefined. +#define AM_REG_WDT_CFG_CLKSEL_S 24 +#define AM_REG_WDT_CFG_CLKSEL_M 0x07000000 +#define AM_REG_WDT_CFG_CLKSEL(n) (((uint32_t)(n) << 24) & 0x07000000) +#define AM_REG_WDT_CFG_CLKSEL_OFF 0x00000000 +#define AM_REG_WDT_CFG_CLKSEL_128HZ 0x01000000 +#define AM_REG_WDT_CFG_CLKSEL_16HZ 0x02000000 +#define AM_REG_WDT_CFG_CLKSEL_1HZ 0x03000000 +#define AM_REG_WDT_CFG_CLKSEL_1_16HZ 0x04000000 + +// This bitfield is the compare value for counter bits 7:0 to generate a +// watchdog interrupt. +#define AM_REG_WDT_CFG_INTVAL_S 16 +#define AM_REG_WDT_CFG_INTVAL_M 0x00FF0000 +#define AM_REG_WDT_CFG_INTVAL(n) (((uint32_t)(n) << 16) & 0x00FF0000) + +// This bitfield is the compare value for counter bits 7:0 to generate a +// watchdog reset. +#define AM_REG_WDT_CFG_RESVAL_S 8 +#define AM_REG_WDT_CFG_RESVAL_M 0x0000FF00 +#define AM_REG_WDT_CFG_RESVAL(n) (((uint32_t)(n) << 8) & 0x0000FF00) + +// This bitfield enables the WDT reset. +#define AM_REG_WDT_CFG_RESEN_S 2 +#define AM_REG_WDT_CFG_RESEN_M 0x00000004 +#define AM_REG_WDT_CFG_RESEN(n) (((uint32_t)(n) << 2) & 0x00000004) + +// This bitfield enables the WDT interrupt. Note : This bit must be set before +// the interrupt status bit will reflect a watchdog timer expiration. The IER +// interrupt register must also be enabled for a WDT interrupt to be sent to the +// NVIC. +#define AM_REG_WDT_CFG_INTEN_S 1 +#define AM_REG_WDT_CFG_INTEN_M 0x00000002 +#define AM_REG_WDT_CFG_INTEN(n) (((uint32_t)(n) << 1) & 0x00000002) + +// This bitfield enables the WDT. +#define AM_REG_WDT_CFG_WDTEN_S 0 +#define AM_REG_WDT_CFG_WDTEN_M 0x00000001 +#define AM_REG_WDT_CFG_WDTEN(n) (((uint32_t)(n) << 0) & 0x00000001) + +//***************************************************************************** +// +// WDT_RSTRT - Restart the watchdog timer +// +//***************************************************************************** +// Writing 0xB2 to WDTRSTRT restarts the watchdog timer. +#define AM_REG_WDT_RSTRT_RSTRT_S 0 +#define AM_REG_WDT_RSTRT_RSTRT_M 0x000000FF +#define AM_REG_WDT_RSTRT_RSTRT(n) (((uint32_t)(n) << 0) & 0x000000FF) +#define AM_REG_WDT_RSTRT_RSTRT_KEYVALUE 0x000000B2 + +//***************************************************************************** +// +// WDT_LOCK - Locks the WDT +// +//***************************************************************************** +// Writing 0x3A locks the watchdog timer. Once locked, the WDTCFG reg cannot be +// written and WDTEN is set. +#define AM_REG_WDT_LOCK_LOCK_S 0 +#define AM_REG_WDT_LOCK_LOCK_M 0x000000FF +#define AM_REG_WDT_LOCK_LOCK(n) (((uint32_t)(n) << 0) & 0x000000FF) +#define AM_REG_WDT_LOCK_LOCK_KEYVALUE 0x0000003A + +//***************************************************************************** +// +// WDT_COUNT - Current Counter Value for WDT +// +//***************************************************************************** +// Read-Only current value of the WDT counter +#define AM_REG_WDT_COUNT_COUNT_S 0 +#define AM_REG_WDT_COUNT_COUNT_M 0x000000FF +#define AM_REG_WDT_COUNT_COUNT(n) (((uint32_t)(n) << 0) & 0x000000FF) + +#endif // AM_REG_WDT_H diff --git a/bsp/apollo2/libraries/startup/SConscript b/bsp/apollo2/libraries/startup/SConscript new file mode 100644 index 0000000000..e4758f1e2e --- /dev/null +++ b/bsp/apollo2/libraries/startup/SConscript @@ -0,0 +1,26 @@ +import rtconfig +Import('RTT_ROOT') +from building import * + +# get current directory +cwd = GetCurrentDir() + +src = Split(""" + +""") + +# add for startup script +if rtconfig.CROSS_TOOL == 'gcc': + src = src + ['gcc_ride7/' + 'startup_gcc.c'] +elif rtconfig.CROSS_TOOL == 'keil': + src = src + ['arm/' + 'startup_keil.s'] +elif rtconfig.CROSS_TOOL == 'iar': + src = src + ['iar/' + 'startup_iar.c'] + +path = [cwd] + +CPPDEFINES = ['AM_PACKAGE_BGA', 'AM_PART_APOLLO2', 'keil'] + +group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) + +Return('group') diff --git a/bsp/apollo2/libraries/startup/arm/startup_keil.s b/bsp/apollo2/libraries/startup/arm/startup_keil.s new file mode 100644 index 0000000000..9c14224cc6 --- /dev/null +++ b/bsp/apollo2/libraries/startup/arm/startup_keil.s @@ -0,0 +1,359 @@ +;****************************************************************************** +; +;! @file startup_keil.s +;! +;! @brief Definitions for Apollo2 interrupt handlers, the vector table, and the stack. +; +;****************************************************************************** + +;****************************************************************************** +; +; Copyright (c) 2017, 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. +; +; 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 1.2.9 of the AmbiqSuite Development Package. +; +;****************************************************************************** + +;****************************************************************************** +; +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +;************************************************************************ +Stack EQU 0x00001000 + +;****************************************************************************** +; +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; +;****************************************************************************** +Heap EQU 0x00000000 + +;****************************************************************************** +; +; Allocate space for the stack. +; +;****************************************************************************** + AREA STACK, NOINIT, READWRITE, ALIGN=3 +StackMem + SPACE Stack +__initial_sp + +;****************************************************************************** +; +; Allocate space for the heap. +; +;****************************************************************************** + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +HeapMem + SPACE Heap +__heap_limit + +;****************************************************************************** +; +; Indicate that the code in this file preserves 8-byte alignment of the stack. +; +;****************************************************************************** + PRESERVE8 + +;****************************************************************************** +; +; Place code into the reset code section. +; +;****************************************************************************** + AREA RESET, CODE, READONLY + THUMB + +;****************************************************************************** +; +; The vector table. +; +;****************************************************************************** +; +; 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. +; + + EXPORT __Vectors +__Vectors + DCD StackMem + Stack ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemoryManagement_Handler ; The MPU fault handler + DCD BusFault_Handler ; The bus fault handler + DCD UsageFault_Handler ; The usage fault handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall handler + DCD DebugMon_Handler ; Debug monitor handler + DCD 0 ; Reserved + DCD PendSV_Handler ; The PendSV handler + DCD SysTick_Handler ; The SysTick handler + + ; Peripheral Interrupts + DCD am_brownout_isr ; 0: Reserved + DCD am_watchdog_isr ; 1: Reserved + DCD am_clkgen_isr ; 2: CLKGEN + DCD am_vcomp_isr ; 3: Voltage Comparator + DCD am_ioslave_ios_isr ; 4: I/O Slave general + DCD am_ioslave_acc_isr ; 5: I/O Slave access + DCD am_iomaster0_isr ; 6: I/O Master 0 + DCD am_iomaster1_isr ; 7: I/O Master 1 + DCD am_iomaster2_isr ; 8: I/O Master 2 + DCD am_iomaster3_isr ; 9: I/O Master 3 + DCD am_iomaster4_isr ; 10: I/O Master 4 + DCD am_iomaster5_isr ; 11: I/O Master 5 + DCD am_gpio_isr ; 12: GPIO + DCD am_ctimer_isr ; 13: CTIMER + DCD am_uart0_isr ; 14: UART0 + DCD am_uart1_isr ; 15: UART1 + DCD am_adc_isr ; 16: ADC + DCD am_pdm_isr ; 17: PDM + DCD am_stimer_isr ; 18: SYSTEM TIMER + DCD am_stimer_cmpr0_isr ; 19: SYSTEM TIMER COMPARE0 + DCD am_stimer_cmpr1_isr ; 20: SYSTEM TIMER COMPARE1 + DCD am_stimer_cmpr2_isr ; 21: SYSTEM TIMER COMPARE2 + DCD am_stimer_cmpr3_isr ; 22: SYSTEM TIMER COMPARE3 + DCD am_stimer_cmpr4_isr ; 23: SYSTEM TIMER COMPARE4 + DCD am_stimer_cmpr5_isr ; 24: SYSTEM TIMER COMPARE5 + DCD am_stimer_cmpr6_isr ; 25: SYSTEM TIMER COMPARE6 + DCD am_stimer_cmpr7_isr ; 26: SYSTEM TIMER COMPARE7 + DCD am_flash_isr ; 27: FLASH + DCD am_software0_isr ; 28: SOFTWARE0 + DCD am_software1_isr ; 29: SOFTWARE1 + DCD am_software2_isr ; 30: SOFTWARE2 + DCD am_software3_isr ; 31: SOFTWARE3 + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + +;****************************************************************************** +; +; This is the code that gets called when the processor first starts execution +; following a reset event. +; +;****************************************************************************** +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT __main + + ; Enable the FPU. + MOVW R0, #0xED88 + MOVT R0, #0xE000 + LDR R1, [R0] + ORR R1, #0x00F00000 + STR R1, [R0] + DSB + ISB + + ; Branch to main. + LDR R0, =__main + BX R0 + + ENDP + +;****************************************************************************** +; +; Weak Exception Handlers. +; +;****************************************************************************** +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemoryManagement_Handler\ + PROC + EXPORT MemoryManagement_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP +am_default_isr PROC + + EXPORT am_brownout_isr [WEAK] + EXPORT am_watchdog_isr [WEAK] + EXPORT am_clkgen_isr [WEAK] + EXPORT am_vcomp_isr [WEAK] + EXPORT am_ioslave_ios_isr [WEAK] + EXPORT am_ioslave_acc_isr [WEAK] + EXPORT am_iomaster0_isr [WEAK] + EXPORT am_iomaster1_isr [WEAK] + EXPORT am_iomaster2_isr [WEAK] + EXPORT am_iomaster3_isr [WEAK] + EXPORT am_iomaster4_isr [WEAK] + EXPORT am_iomaster5_isr [WEAK] + EXPORT am_gpio_isr [WEAK] + EXPORT am_ctimer_isr [WEAK] + EXPORT am_uart0_isr [WEAK] + EXPORT am_uart1_isr [WEAK] + EXPORT am_adc_isr [WEAK] + EXPORT am_pdm_isr [WEAK] + EXPORT am_stimer_isr [WEAK] + EXPORT am_stimer_cmpr0_isr [WEAK] + EXPORT am_stimer_cmpr1_isr [WEAK] + EXPORT am_stimer_cmpr2_isr [WEAK] + EXPORT am_stimer_cmpr3_isr [WEAK] + EXPORT am_stimer_cmpr4_isr [WEAK] + EXPORT am_stimer_cmpr5_isr [WEAK] + EXPORT am_stimer_cmpr6_isr [WEAK] + EXPORT am_stimer_cmpr7_isr [WEAK] + EXPORT am_flash_isr [WEAK] + EXPORT am_software0_isr [WEAK] + EXPORT am_software1_isr [WEAK] + EXPORT am_software2_isr [WEAK] + EXPORT am_software3_isr [WEAK] + +am_brownout_isr +am_watchdog_isr +am_clkgen_isr +am_vcomp_isr +am_ioslave_ios_isr +am_ioslave_acc_isr +am_iomaster0_isr +am_iomaster1_isr +am_iomaster2_isr +am_iomaster3_isr +am_iomaster4_isr +am_iomaster5_isr +am_gpio_isr +am_ctimer_isr +am_uart0_isr +am_uart1_isr +am_adc_isr +am_pdm_isr +am_stimer_isr +am_stimer_cmpr0_isr +am_stimer_cmpr1_isr +am_stimer_cmpr2_isr +am_stimer_cmpr3_isr +am_stimer_cmpr4_isr +am_stimer_cmpr5_isr +am_stimer_cmpr6_isr +am_stimer_cmpr7_isr +am_flash_isr +am_software0_isr +am_software1_isr +am_software2_isr +am_software3_isr + + ; all device interrupts go here unless the weak label is over + ; ridden in the linker hard spin so the debugger will know it + ; was an unhandled interrupt request a come-from-buffer or + ; instruction trace hardware would sure be nice if you get here + B . + + ENDP + +;****************************************************************************** +; +; Align the end of the section. +; +;****************************************************************************** + ALIGN + +;****************************************************************************** +; +; Initialization of the heap and stack. +; +;****************************************************************************** + AREA |.text|, CODE, READONLY + +;****************************************************************************** +; +; User Initial Stack & Heap. +; +;****************************************************************************** + IF :DEF: __MICROLIB + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + ELSE + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap +__user_initial_stackheap PROC + LDR R0, =HeapMem + LDR R1, =(StackMem + Stack) + LDR R2, =(HeapMem + Heap) + LDR R3, =StackMem + BX LR + + ENDP + + ENDIF + +;****************************************************************************** +; +; Align the end of the section. +; +;****************************************************************************** + ALIGN + +;****************************************************************************** +; +; All Done +; +;****************************************************************************** + END + + diff --git a/bsp/apollo2/libraries/startup/gcc/startup_gcc.c b/bsp/apollo2/libraries/startup/gcc/startup_gcc.c new file mode 100644 index 0000000000..a67dff41f4 --- /dev/null +++ b/bsp/apollo2/libraries/startup/gcc/startup_gcc.c @@ -0,0 +1,316 @@ +//***************************************************************************** +// +//! @file startup_gcc.c +//! +//! @brief Definitions for interrupt handlers, the vector table, and the stack. +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include + +//***************************************************************************** +// +// Forward declaration of interrupt handlers. +// +//***************************************************************************** +extern void am_reset_isr(void) __attribute ((naked)); +extern void am_nmi_isr(void) __attribute ((weak)); +extern void am_fault_isr(void) __attribute ((weak)); +extern void am_mpufault_isr(void) __attribute ((weak, alias ("am_fault_isr"))); +extern void am_busfault_isr(void) __attribute ((weak, alias ("am_fault_isr"))); +extern void am_usagefault_isr(void) __attribute ((weak, alias ("am_fault_isr"))); +extern void am_svcall_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_debugmon_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_pendsv_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_systick_isr(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_clkgen_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_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_adc_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_pdm_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_flash_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_software0_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_software1_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_software2_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_software3_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[1024]; + +//***************************************************************************** +// +// 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 + am_reset_isr, // The reset handler + am_nmi_isr, // The NMI handler + am_fault_isr, // The hard fault handler + am_fault_isr, // The MPU fault handler + am_fault_isr, // The bus fault handler + am_fault_isr, // The usage fault handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + am_svcall_isr, // SVCall handle + am_debugmon_isr, // Debug monitor handler + 0, // Reserved + am_pendsv_isr, // The PendSV handler + am_systick_isr, // The SysTick handler + + // + // Peripheral Interrupts + // + am_brownout_isr, // 0: Brownout + am_watchdog_isr, // 1: Watchdog + am_clkgen_isr, // 2: CLKGEN + 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_gpio_isr, // 12: GPIO + am_ctimer_isr, // 13: CTIMER + am_uart_isr, // 14: UART + am_uart1_isr, // 15: UART + am_adc_isr, // 16: ADC + am_pdm_isr, // 17: ADC + am_stimer_isr, // 18: SYSTEM TIMER + am_stimer_cmpr0_isr, // 19: SYSTEM TIMER COMPARE0 + am_stimer_cmpr1_isr, // 20: SYSTEM TIMER COMPARE1 + am_stimer_cmpr2_isr, // 21: SYSTEM TIMER COMPARE2 + am_stimer_cmpr3_isr, // 22: SYSTEM TIMER COMPARE3 + am_stimer_cmpr4_isr, // 23: SYSTEM TIMER COMPARE4 + am_stimer_cmpr5_isr, // 24: SYSTEM TIMER COMPARE5 + am_stimer_cmpr6_isr, // 25: SYSTEM TIMER COMPARE6 + am_stimer_cmpr7_isr, // 26: SYSTEM TIMER COMPARE7 + am_flash_isr, // 27: FLASH + am_software0_isr, // 28: SOFTWARE0 + am_software1_isr, // 29: SOFTWARE1 + am_software2_isr, // 30: SOFTWARE2 + am_software3_isr // 31: SOFTWARE3 +}; + +//***************************************************************************** +// +// 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 +am_reset_isr(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 +am_nmi_isr(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 +am_fault_isr(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) + { + } +} + diff --git a/bsp/apollo2/libraries/startup/iar/startup_iar.c b/bsp/apollo2/libraries/startup/iar/startup_iar.c new file mode 100644 index 0000000000..3264300cb4 --- /dev/null +++ b/bsp/apollo2/libraries/startup/iar/startup_iar.c @@ -0,0 +1,312 @@ +//***************************************************************************** +// +//! @file startup_iar.c +//! +//! @brief Definitions for interrupt handlers, the vector table, and the stack. +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2017, 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. +// +// 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 1.2.9 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include + +//***************************************************************************** +// +// Enable the IAR extensions for this source file. +// +//***************************************************************************** +#pragma language = extended + +//***************************************************************************** +// +// Weak function links. +// +//***************************************************************************** +#pragma weak am_mpufault_isr = am_fault_isr +#pragma weak am_busfault_isr = am_fault_isr +#pragma weak am_usagefault_isr = am_fault_isr +#pragma weak am_svcall_isr = am_default_isr +#pragma weak am_debugmon_isr = am_default_isr +#pragma weak am_pendsv_isr = am_default_isr +#pragma weak am_systick_isr = am_default_isr +#pragma weak am_brownout_isr = am_default_isr +#pragma weak am_watchdog_isr = am_default_isr +#pragma weak am_clkgen_isr = am_default_isr +#pragma weak am_vcomp_isr = am_default_isr +#pragma weak am_ioslave_ios_isr = am_default_isr +#pragma weak am_ioslave_acc_isr = am_default_isr +#pragma weak am_iomaster0_isr = am_default_isr +#pragma weak am_iomaster1_isr = am_default_isr +#pragma weak am_iomaster2_isr = am_default_isr +#pragma weak am_iomaster3_isr = am_default_isr +#pragma weak am_iomaster4_isr = am_default_isr +#pragma weak am_iomaster5_isr = am_default_isr +#pragma weak am_gpio_isr = am_default_isr +#pragma weak am_ctimer_isr = am_default_isr +#pragma weak am_uart_isr = am_default_isr +#pragma weak am_uart1_isr = am_default_isr +#pragma weak am_adc_isr = am_default_isr +#pragma weak am_pdm_isr = am_default_isr +#pragma weak am_stimer_isr = am_default_isr +#pragma weak am_stimer_cmpr0_isr = am_default_isr +#pragma weak am_stimer_cmpr1_isr = am_default_isr +#pragma weak am_stimer_cmpr2_isr = am_default_isr +#pragma weak am_stimer_cmpr3_isr = am_default_isr +#pragma weak am_stimer_cmpr4_isr = am_default_isr +#pragma weak am_stimer_cmpr5_isr = am_default_isr +#pragma weak am_stimer_cmpr6_isr = am_default_isr +#pragma weak am_stimer_cmpr7_isr = am_default_isr +#pragma weak am_flash_isr = am_default_isr +#pragma weak am_software0_isr = am_default_isr +#pragma weak am_software1_isr = am_default_isr +#pragma weak am_software2_isr = am_default_isr +#pragma weak am_software3_isr = am_default_isr + + +//***************************************************************************** +// +// Forward declaration of the default fault handlers. +// +//***************************************************************************** +extern __stackless void am_reset_isr(void); +extern __weak void am_nmi_isr(void); +extern __weak void am_fault_isr(void); +extern void am_mpufault_isr(void); +extern void am_busfault_isr(void); +extern void am_usagefault_isr(void); +extern void am_svcall_isr(void); +extern void am_debugmon_isr(void); +extern void am_pendsv_isr(void); +extern void am_systick_isr(void); +extern void am_brownout_isr(void); +extern void am_watchdog_isr(void); +extern void am_clkgen_isr(void); +extern void am_vcomp_isr(void); +extern void am_ioslave_ios_isr(void); +extern void am_ioslave_acc_isr(void); +extern void am_iomaster0_isr(void); +extern void am_iomaster1_isr(void); +extern void am_iomaster2_isr(void); +extern void am_iomaster3_isr(void); +extern void am_iomaster4_isr(void); +extern void am_iomaster5_isr(void); +extern void am_gpio_isr(void); +extern void am_ctimer_isr(void); +extern void am_uart_isr(void); +extern void am_uart1_isr(void); +extern void am_adc_isr(void); +extern void am_pdm_isr(void); +extern void am_stimer_isr(void); +extern void am_stimer_cmpr0_isr(void); +extern void am_stimer_cmpr1_isr(void); +extern void am_stimer_cmpr2_isr(void); +extern void am_stimer_cmpr3_isr(void); +extern void am_stimer_cmpr4_isr(void); +extern void am_stimer_cmpr5_isr(void); +extern void am_stimer_cmpr6_isr(void); +extern void am_stimer_cmpr7_isr(void); +extern void am_flash_isr(void); +extern void am_software0_isr(void); +extern void am_software1_isr(void); +extern void am_software2_isr(void); +extern void am_software3_isr(void); + +extern void am_default_isr(void); + +//***************************************************************************** +// +// The entry point for the application startup code. +// +//***************************************************************************** +extern void __iar_program_start(void); + +//***************************************************************************** +// +// Reserve space for the system stack. +// +//***************************************************************************** +static uint32_t pui32Stack[1024] @ ".noinit"; + +//***************************************************************************** +// +// A union that describes the entries of the vector table. The union is needed +// since the first entry is the stack pointer and the remainder are function +// pointers. +// +//***************************************************************************** +typedef union +{ + void (*pfnHandler)(void); + uint32_t ui32Ptr; +} +uVectorEntry; + +//***************************************************************************** +// +// 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. +// +//***************************************************************************** +__root const uVectorEntry __vector_table[] @ ".intvec" = +{ + { .ui32Ptr = (uint32_t)pui32Stack + sizeof(pui32Stack) }, + // The initial stack pointer + am_reset_isr, // The reset handler + am_nmi_isr, // The NMI handler + am_fault_isr, // The hard fault handler + am_fault_isr, // The MPU fault handler + am_fault_isr, // The bus fault handler + am_fault_isr, // The usage fault handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + am_svcall_isr, // SVCall handle + am_debugmon_isr, // Debug monitor handler + 0, // Reserved + am_pendsv_isr, // The PendSV handler + am_systick_isr, // The SysTick handler + + // + // Peripheral Interrupts + // + am_brownout_isr, // 0: Brownout + am_watchdog_isr, // 1: Watchdog + am_clkgen_isr, // 2: CLKGEN + 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_gpio_isr, // 12: GPIO + am_ctimer_isr, // 13: CTIMER + am_uart_isr, // 14: UART0 + am_uart1_isr, // 15: UART1 + am_adc_isr, // 16: ADC + am_pdm_isr, // 17: PDM + am_stimer_isr, // 18: STIMER + am_stimer_cmpr0_isr, // 19: STIMER COMPARE0 + am_stimer_cmpr1_isr, // 20: STIMER COMPARE1 + am_stimer_cmpr2_isr, // 21: STIMER COMPARE2 + am_stimer_cmpr3_isr, // 22: STIMER COMPARE3 + am_stimer_cmpr4_isr, // 23: STIMER COMPARE4 + am_stimer_cmpr5_isr, // 24: STIMER COMPARE5 + am_stimer_cmpr6_isr, // 25: STIMER COMPARE6 + am_stimer_cmpr7_isr, // 26: STIMER COMPARE7 + am_flash_isr, // 27: FLASH + am_software0_isr, // 28: SOFTWARE0 + am_software1_isr, // 29: SOFTWARE1 + am_software2_isr, // 30: SOFTWARE2 + am_software3_isr // 31: SOFTWARE3 +}; + +//***************************************************************************** +// +// 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. +// +//***************************************************************************** +void +am_reset_isr(void) +{ + // + // Call the application's entry point. + // + __iar_program_start(); +} + +//***************************************************************************** +// +// 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. +// +//***************************************************************************** +__weak void +am_nmi_isr(void) +{ + // + // Enter 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. +// +//***************************************************************************** +__weak void +am_fault_isr(void) +{ + // + // Enter 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. +// +//***************************************************************************** +static void +am_default_isr(void) +{ + // + // Go into an infinite loop. + // + while(1) + { + } +} diff --git a/bsp/apollo2/project.uvprojx b/bsp/apollo2/project.uvprojx new file mode 100644 index 0000000000..6e5bcba4b4 --- /dev/null +++ b/bsp/apollo2/project.uvprojx @@ -0,0 +1,740 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + rtthread-apollo2 + 0x4 + ARM-ADS + 5060061::V5.06 update 1 (build 61)::ARMCC + + + AMAPH1KK-KBR + Ambiq Micro + AmbiqMicro.Apollo_DFP.1.0.0 + http://s3.asia.ambiqmicro.com/pack/ + IROM(0x00000000,0x100000) IRAM(0x10000000,0x40000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD10000000 -FC4000 -FN1 -FF0Apollo2 -FS00 -FL010000 -FP0($$Device:AMAPH1KK-KBR$Flash\Apollo2.FLM)) + 0 + $$Device:AMAPH1KK-KBR$Device\Include\apollo2.h + + + + + + + + + + $$Device:AMAPH1KK-KBR$SVD\apollo2.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\ + rtthread + 1 + 0 + 0 + 1 + 1 + .\build\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + fromelf --bin !L --output rtthread.bin + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + + + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + + 0 + 6 + + + + + + + + + + + + + + Segger\JL2CM3.dll + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x10000000 + 0x40000 + + + 1 + 0x0 + 0x100000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x100000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x10000000 + 0x40000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + 1 + 1 + 1 + 1 + + + AM_PART_APOLLO2, AM_PACKAGE_BGA, keil + + applications;.;board;libraries\drivers;libraries\startup;..\..\include;..\..\libcpu\arm\cortex-m4;..\..\libcpu\arm\common;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\finsh + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\build\rtthread.sct + + + --keep *.o(.rti_fn.*) --keep *.o(FSymTab) --keep *.o(VSymTab) + + + + + + + + Applications + + + application.c + 1 + applications\application.c + + + startup.c + 1 + applications\startup.c + + + + + Board + + + board.c + 1 + board\board.c + + + hw_led.c + 1 + board\hw_led.c + + + hw_uart.c + 1 + board\hw_uart.c + + + + + Libraries + + + am_hal_clkgen.c + 1 + libraries\drivers\hal\am_hal_clkgen.c + + + am_hal_debug.c + 1 + libraries\drivers\hal\am_hal_debug.c + + + am_hal_cachectrl.c + 1 + libraries\drivers\hal\am_hal_cachectrl.c + + + am_hal_pwrctrl.c + 1 + libraries\drivers\hal\am_hal_pwrctrl.c + + + am_hal_sysctrl.c + 1 + libraries\drivers\hal\am_hal_sysctrl.c + + + am_hal_stimer.c + 1 + libraries\drivers\hal\am_hal_stimer.c + + + am_hal_ctimer.c + 1 + libraries\drivers\hal\am_hal_ctimer.c + + + am_hal_rtc.c + 1 + libraries\drivers\hal\am_hal_rtc.c + + + am_hal_interrupt.c + 1 + libraries\drivers\hal\am_hal_interrupt.c + + + am_hal_queue.c + 1 + libraries\drivers\hal\am_hal_queue.c + + + am_hal_vcomp.c + 1 + libraries\drivers\hal\am_hal_vcomp.c + + + am_hal_flash.c + 1 + libraries\drivers\hal\am_hal_flash.c + + + am_hal_gpio.c + 1 + libraries\drivers\hal\am_hal_gpio.c + + + am_hal_uart.c + 1 + libraries\drivers\hal\am_hal_uart.c + + + startup_keil.s + 2 + libraries\startup\arm\startup_keil.s + + + + + Kernel + + + clock.c + 1 + ..\..\src\clock.c + + + components.c + 1 + ..\..\src\components.c + + + device.c + 1 + ..\..\src\device.c + + + idle.c + 1 + ..\..\src\idle.c + + + ipc.c + 1 + ..\..\src\ipc.c + + + irq.c + 1 + ..\..\src\irq.c + + + kservice.c + 1 + ..\..\src\kservice.c + + + mem.c + 1 + ..\..\src\mem.c + + + object.c + 1 + ..\..\src\object.c + + + scheduler.c + 1 + ..\..\src\scheduler.c + + + thread.c + 1 + ..\..\src\thread.c + + + timer.c + 1 + ..\..\src\timer.c + + + + + CORTEX-M4 + + + cpuport.c + 1 + ..\..\libcpu\arm\cortex-m4\cpuport.c + + + context_rvds.S + 2 + ..\..\libcpu\arm\cortex-m4\context_rvds.S + + + backtrace.c + 1 + ..\..\libcpu\arm\common\backtrace.c + + + div0.c + 1 + ..\..\libcpu\arm\common\div0.c + + + showmem.c + 1 + ..\..\libcpu\arm\common\showmem.c + + + + + DeviceDrivers + + + serial.c + 1 + ..\..\components\drivers\serial\serial.c + + + completion.c + 1 + ..\..\components\drivers\src\completion.c + + + dataqueue.c + 1 + ..\..\components\drivers\src\dataqueue.c + + + pipe.c + 1 + ..\..\components\drivers\src\pipe.c + + + portal.c + 1 + ..\..\components\drivers\src\portal.c + + + ringbuffer.c + 1 + ..\..\components\drivers\src\ringbuffer.c + + + workqueue.c + 1 + ..\..\components\drivers\src\workqueue.c + + + + + finsh + + + shell.c + 1 + ..\..\components\finsh\shell.c + + + symbol.c + 1 + ..\..\components\finsh\symbol.c + + + cmd.c + 1 + ..\..\components\finsh\cmd.c + + + finsh_compiler.c + 1 + ..\..\components\finsh\finsh_compiler.c + + + finsh_error.c + 1 + ..\..\components\finsh\finsh_error.c + + + finsh_heap.c + 1 + ..\..\components\finsh\finsh_heap.c + + + finsh_init.c + 1 + ..\..\components\finsh\finsh_init.c + + + finsh_node.c + 1 + ..\..\components\finsh\finsh_node.c + + + finsh_ops.c + 1 + ..\..\components\finsh\finsh_ops.c + + + finsh_parser.c + 1 + ..\..\components\finsh\finsh_parser.c + + + finsh_var.c + 1 + ..\..\components\finsh\finsh_var.c + + + finsh_vm.c + 1 + ..\..\components\finsh\finsh_vm.c + + + finsh_token.c + 1 + ..\..\components\finsh\finsh_token.c + + + + + + + +
diff --git a/bsp/apollo2/rtconfig.h b/bsp/apollo2/rtconfig.h new file mode 100644 index 0000000000..759cd4078a --- /dev/null +++ b/bsp/apollo2/rtconfig.h @@ -0,0 +1,93 @@ +/* RT-Thread config file */ +#ifndef __RTTHREAD_CFG_H__ +#define __RTTHREAD_CFG_H__ + +/* RT_NAME_MAX*/ +#define RT_NAME_MAX 6 + +/* RT_ALIGN_SIZE*/ +#define RT_ALIGN_SIZE 4 + +/* PRIORITY_MAX */ +#define RT_THREAD_PRIORITY_MAX 8 + +/* Tick per Second */ +#define RT_TICK_PER_SECOND 200 + +/* SECTION: RT_DEBUG */ +/* Thread Debug */ +#define RT_DEBUG +//#define RT_DEBUG_INIT 1 +#define RT_USING_OVERFLOW_CHECK + +/* Using Hook */ +//#define RT_USING_HOOK + +//#define RT_USING_IDLE_HOOK + +#define IDLE_THREAD_STACK_SIZE 384 + +/* Using Software Timer */ +//#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 1 +#define RT_TIMER_THREAD_STACK_SIZE 512 +#define RT_TIMER_TICK_PER_SECOND 200 + +/* SECTION: IPC */ +/* Using Semaphore*/ +#define RT_USING_SEMAPHORE + +/* Using Mutex */ +#define RT_USING_MUTEX + +/* Using Event */ +#define RT_USING_EVENT + +/* Using MailBox */ +/* #define RT_USING_MAILBOX */ + +/* Using Message Queue */ +#define RT_USING_MESSAGEQUEUE + +/* SECTION: Memory Management */ +/* Using Memory Pool Management*/ +/* #define RT_USING_MEMPOOL */ + +/* Using Dynamic Heap Management */ +#define RT_USING_HEAP + +/* Using Small MM */ +#define RT_USING_SMALL_MEM +#define RT_USING_TINY_SIZE + +// +#define RT_USING_COMPONENTS_INIT + +/* SECTION: Device System */ +/* Using Device System */ +#define RT_USING_DEVICE +// +#define RT_USING_DEVICE_IPC +// +#define RT_USING_SERIAL + +/* SECTION: Console options */ +#define RT_USING_CONSOLE +/* the buffer size of console*/ +#define RT_CONSOLEBUF_SIZE 128 +// +#define RT_CONSOLE_DEVICE_NAME "uart0" + +// #define RT_USING_SPI + +/* SECTION: finsh, a C-Express shell */ +#define RT_USING_FINSH +/* configure finsh parameters */ +#define FINSH_THREAD_PRIORITY 6 +#define FINSH_THREAD_STACK_SIZE 512 +#define FINSH_HISTORY_LINES 1 +/* Using symbol table */ +#define FINSH_USING_SYMTAB +#define FINSH_USING_DESCRIPTION + +#endif diff --git a/bsp/apollo2/rtconfig.py b/bsp/apollo2/rtconfig.py new file mode 100644 index 0000000000..5e40e7201e --- /dev/null +++ b/bsp/apollo2/rtconfig.py @@ -0,0 +1,84 @@ +import os + +# toolchains options +ARCH='arm' +CPU='cortex-m4' +CROSS_TOOL='keil' + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') + +# cross_tool provides the cross compiler +# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR + +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + EXEC_PATH = 'D:/SourceryGCC/bin' +elif CROSS_TOOL == 'keil': + PLATFORM = 'armcc' + EXEC_PATH = 'C:/Keil_v5' +elif CROSS_TOOL == 'iar': + print '================ERROR============================' + print 'Not support iar yet!' + print '=================================================' + exit(0) + +if os.getenv('RTT_EXEC_PATH'): + EXEC_PATH = os.getenv('RTT_EXEC_PATH') + +BUILD = 'debug' + +if PLATFORM == 'gcc': + # toolchains + PREFIX = 'arm-none-eabi-' + CC = PREFIX + 'gcc' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'axf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + + DEVICE = ' -mcpu=cortex-m4 -mthumb -ffunction-sections -fdata-sections' + CFLAGS = DEVICE + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-nrf52832.map,-cref,-u,Reset_Handler -T nrf52_xxaa.ld' + + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -gdwarf-2' + AFLAGS += ' -gdwarf-2' + else: + CFLAGS += ' -O2' + + POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' + +elif PLATFORM == 'armcc': + # toolchains + CC = 'armcc' + AS = 'armasm' + AR = 'armar' + LINK = 'armlink' + TARGET_EXT = 'axf' + + DEVICE = ' --device DARMSTM' + CFLAGS = DEVICE + ' --apcs=interwork' + AFLAGS = DEVICE + LFLAGS = DEVICE + ' --info sizes --info totals --info unused --info veneers --list rtthread-nrf52832.map --scatter rtthread-nrf52832.sct' + + CFLAGS += ' --c99' + CFLAGS += ' -I' + EXEC_PATH + '/ARM/RV31/INC' + LFLAGS += ' --libpath ' + EXEC_PATH + '/ARM/RV31/LIB' + + EXEC_PATH += '/arm/bin40/' + + if BUILD == 'debug': + CFLAGS += ' -g -O0' + AFLAGS += ' -g' + else: + CFLAGS += ' -O2' + + POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET' diff --git a/bsp/apollo2/template.uvoptx b/bsp/apollo2/template.uvoptx new file mode 100644 index 0000000000..e6bfeb7bb2 --- /dev/null +++ b/bsp/apollo2/template.uvoptx @@ -0,0 +1,164 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + rtthread-apollo2 + 0x4 + ARM-ADS + + 48000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\build\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 0 + 0 + 1 + + 255 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 6 + + + + + + + + + + + Segger\JL2CM3.dll + + + + 0 + JL2CM3 + -U4294967295 -O78 -S0 -ZTIFSpeedSel20000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD10000000 -FC4000 -FN1 -FF0Apollo2.FLM -FS00 -FL010000 -FP0($$Device:AMAPH1KK-KBR$Flash\Apollo2.FLM) + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD10000000 -FC4000 -FN1 -FF0Apollo2 -FS00 -FL010000 -FP0($$Device:AMAPH1KK-KBR$Flash\Apollo2.FLM)) + + + + + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + + + +
diff --git a/bsp/apollo2/template.uvprojx b/bsp/apollo2/template.uvprojx new file mode 100644 index 0000000000..eef72b7995 --- /dev/null +++ b/bsp/apollo2/template.uvprojx @@ -0,0 +1,418 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + rtthread-apollo2 + 0x4 + ARM-ADS + 5060061::V5.06 update 1 (build 61)::ARMCC + + + AMAPH1KK-KBR + Ambiq Micro + AmbiqMicro.Apollo_DFP.1.0.0 + http://s3.asia.ambiqmicro.com/pack/ + IROM(0x00000000,0x100000) IRAM(0x10000000,0x40000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD10000000 -FC4000 -FN1 -FF0Apollo2 -FS00 -FL010000 -FP0($$Device:AMAPH1KK-KBR$Flash\Apollo2.FLM)) + 0 + $$Device:AMAPH1KK-KBR$Device\Include\apollo2.h + + + + + + + + + + $$Device:AMAPH1KK-KBR$SVD\apollo2.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\ + rtthread + 1 + 0 + 0 + 1 + 1 + .\build\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + fromelf --bin !L --output rtthread.bin + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + + + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + + 0 + 6 + + + + + + + + + + + + + + Segger\JL2CM3.dll + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x10000000 + 0x40000 + + + 1 + 0x0 + 0x100000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x100000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x10000000 + 0x40000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + 1 + 1 + 1 + 1 + + + AM_PACKAGE_BGA,AM_PART_APOLLO2,keil,USE_APDPERIPH_DRIVER + + + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\build\rtthread.sct + + + + + + + + + + + +
From 19fcea522921e8fa93cb35813b1d4babc2e74740 Mon Sep 17 00:00:00 2001 From: lin <429426691@qq.com> Date: Mon, 18 Sep 2017 17:45:46 +0800 Subject: [PATCH 2/5] Modified pin driver and some format --- .../applications/{application.c => main.c} | 48 +-- bsp/apollo2/applications/startup.c | 93 ------ bsp/apollo2/board/gpio.c | 99 ++++++ bsp/apollo2/board/gpio.h | 30 ++ bsp/apollo2/board/hw_led.c | 302 ------------------ bsp/apollo2/board/hw_led.h | 60 ---- bsp/apollo2/board/hw_uart.h | 23 -- bsp/apollo2/board/led.c | 152 +++++++++ bsp/apollo2/board/led.h | 38 +++ bsp/apollo2/board/{hw_uart.c => uart.c} | 292 +++++++++-------- bsp/apollo2/board/uart.h | 30 ++ 11 files changed, 516 insertions(+), 651 deletions(-) rename bsp/apollo2/applications/{application.c => main.c} (60%) delete mode 100644 bsp/apollo2/applications/startup.c create mode 100644 bsp/apollo2/board/gpio.c create mode 100644 bsp/apollo2/board/gpio.h delete mode 100644 bsp/apollo2/board/hw_led.c delete mode 100644 bsp/apollo2/board/hw_led.h delete mode 100644 bsp/apollo2/board/hw_uart.h create mode 100644 bsp/apollo2/board/led.c create mode 100644 bsp/apollo2/board/led.h rename bsp/apollo2/board/{hw_uart.c => uart.c} (52%) create mode 100644 bsp/apollo2/board/uart.h diff --git a/bsp/apollo2/applications/application.c b/bsp/apollo2/applications/main.c similarity index 60% rename from bsp/apollo2/applications/application.c rename to bsp/apollo2/applications/main.c index 80f0963202..dab3fd123f 100644 --- a/bsp/apollo2/applications/application.c +++ b/bsp/apollo2/applications/main.c @@ -1,22 +1,27 @@ /* * File : application.c * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2015, RT-Thread Development Team + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes * 2017-09-14 Haley the first version */ -/** - * @addtogroup APOLLO2 - */ -/*@{*/ - #include #include #ifdef RT_USING_FINSH @@ -24,9 +29,8 @@ #include #endif -#include "hw_led.h" +#include "led.h" -ALIGN(RT_ALIGN_SIZE) static rt_uint8_t led_stack[ 512 ]; static struct rt_thread led_thread; @@ -34,9 +38,6 @@ static void led_thread_entry(void* parameter) { unsigned int count=0; - rt_hw_led_init(0); - rt_hw_led_init(1); - while (1) { /* led1 on */ @@ -56,18 +57,8 @@ static void led_thread_entry(void* parameter) } } -void rt_init_thread_entry(void* parameter) +int main(void) { - #ifdef RT_USING_COMPONENTS_INIT - /* initialization RT-Thread Components */ - rt_components_init(); - #endif -} - -int rt_application_init(void) -{ - rt_thread_t init_thread; - rt_err_t result; /* init led thread */ @@ -77,17 +68,12 @@ int rt_application_init(void) RT_NULL, (rt_uint8_t*)&led_stack[0], sizeof(led_stack), - 7, + RT_THREAD_PRIORITY_MAX/3, 5); if (result == RT_EOK) { rt_thread_startup(&led_thread); } - - init_thread = rt_thread_create("init", rt_init_thread_entry, RT_NULL, 1024, - RT_THREAD_PRIORITY_MAX / 3, 20); - if (init_thread != RT_NULL) - rt_thread_startup(init_thread); return 0; } diff --git a/bsp/apollo2/applications/startup.c b/bsp/apollo2/applications/startup.c deleted file mode 100644 index 5459c51f46..0000000000 --- a/bsp/apollo2/applications/startup.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * File : startup.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2015, RT-Thread Develop Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://openlab.rt-thread.com/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2017-09-11 Haley the first version - */ - -#include -#include - -#include "board.h" - -/** - * @addtogroup Apollo2 - */ - -/*@{*/ - -extern int rt_application_init(void); - -#ifdef __CC_ARM -extern int Image$$RW_IRAM1$$ZI$$Limit; -#define AM_SRAM_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit) -#elif __ICCARM__ -#pragma section="HEAP" -#define AM_SRAM_BEGIN (__segment_end("HEAP")) -#else -extern int __bss_end; -#define NRF_SRAM_BEGIN (&__bss_end) -#endif - -/** - * This function will startup RT-Thread RTOS. - */ -void rtthread_startup(void) -{ - /* init board */ - rt_hw_board_init(); - - /* show version */ - rt_show_version(); - - /* init tick */ - rt_system_tick_init(); - - /* init kernel object */ - rt_system_object_init(); - - /* init timer system */ - rt_system_timer_init(); - -#ifdef RT_USING_HEAP - rt_system_heap_init((void*)AM_SRAM_BEGIN, (void*)AM_SRAM_END); -#endif - - /* init scheduler system */ - rt_system_scheduler_init(); - - /* init application */ - rt_application_init(); - - /* init timer thread */ - rt_system_timer_thread_init(); - - /* init idle thread */ - rt_thread_idle_init(); - - /* start scheduler */ - rt_system_scheduler_start(); - - /* never reach here */ - return ; -} - -int main(void) -{ - /* disable interrupt first */ - // rt_hw_interrupt_disable(); - - /* startup RT-Thread RTOS */ - rtthread_startup(); - - return 0; -} - -/*@}*/ diff --git a/bsp/apollo2/board/gpio.c b/bsp/apollo2/board/gpio.c new file mode 100644 index 0000000000..5c5b5b506c --- /dev/null +++ b/bsp/apollo2/board/gpio.c @@ -0,0 +1,99 @@ +/* + * File : gpio.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-09-16 Haley the first version + */ + +#include +#include +#include "am_mcu_apollo.h" + +#ifdef RT_USING_PIN + +void am_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode) +{ + if (mode == PIN_MODE_OUTPUT) + { + /* output setting */ + am_hal_gpio_pin_config(pin, AM_HAL_GPIO_OUTPUT); + } + else if (mode == PIN_MODE_INPUT) + { + /* input setting: not pull. */ + am_hal_gpio_pin_config(pin, AM_HAL_GPIO_INPUT); + } + else if (mode == PIN_MODE_INPUT_PULLUP) + { + /* input setting: pull up. */ + am_hal_gpio_pin_config(pin, AM_HAL_GPIO_OPENDRAIN); + } + else + { + /* input setting:default. */ + am_hal_gpio_pin_config(pin, AM_HAL_GPIO_INPUT); + } +} + +void am_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value) +{ + if (value == PIN_LOW) + { + am_hal_gpio_out_bit_clear(pin); + } + else + { + am_hal_gpio_out_bit_set(pin); + } +} + +int am_pin_read(rt_device_t dev, rt_base_t pin) +{ + int value = PIN_LOW; + + if (am_hal_gpio_input_bit_read(pin) == 0) + { + value = PIN_LOW; + } + else + { + value = PIN_HIGH; + } + + return value; +} + +const static struct rt_pin_ops _am_pin_ops = +{ + am_pin_mode, + am_pin_write, + am_pin_read, +}; + +int hw_pin_init(void) +{ + rt_device_pin_register("pin", &_am_pin_ops, RT_NULL); + return 0; +} + +INIT_BOARD_EXPORT(hw_pin_init); +#endif + +/*@}*/ diff --git a/bsp/apollo2/board/gpio.h b/bsp/apollo2/board/gpio.h new file mode 100644 index 0000000000..455c262224 --- /dev/null +++ b/bsp/apollo2/board/gpio.h @@ -0,0 +1,30 @@ +/* + * File : gpio.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-09-16 Haley the first version + */ + +#ifndef __GPIO_H +#define __GPIO_H + +int hw_pin_init(void); + +#endif // __GPIO_H diff --git a/bsp/apollo2/board/hw_led.c b/bsp/apollo2/board/hw_led.c deleted file mode 100644 index 71f6c47db5..0000000000 --- a/bsp/apollo2/board/hw_led.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * File : hw_led.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2017, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2017-09-14 Haley the first version - */ - -#include -#include "am_mcu_apollo.h" -#include "hw_led.h" - -#define AM_GPIO_LED0 46 -#define AM_GPIO_LED1 47 -#define AM_GPIO_LED2 48 -#define AM_GPIO_LED3 49 - -#define AM_NUM_LEDS 4 - -rt_hw_led_t am_psLEDs[AM_NUM_LEDS] = -{ - {AM_GPIO_LED0, AM_LED_ON_LOW | AM_LED_POL_DIRECT_DRIVE_M}, - {AM_GPIO_LED1, AM_LED_ON_LOW | AM_LED_POL_DIRECT_DRIVE_M}, - {AM_GPIO_LED2, AM_LED_ON_LOW | AM_LED_POL_DIRECT_DRIVE_M}, - {AM_GPIO_LED3, AM_LED_ON_LOW | AM_LED_POL_DIRECT_DRIVE_M}, -}; - -/** - * @brief Configures the necessary pins for an array of LEDs - * - * @param LEDNum is the LED number. - * - * This function configures a GPIO to drive an LED in a low-power way. - * - * @return None. - */ -void rt_hw_led_init(rt_uint32_t LEDNum) -{ - rt_hw_led_t *psLED = am_psLEDs + LEDNum; - - /* Handle Direct Drive Versus 3-State (with pull-up or no buffer) */ - if ( AM_LED_POL_DIRECT_DRIVE_M & psLED->Polarity ) - { - /* Configure the pin as a push-pull GPIO output */ - am_hal_gpio_pin_config(psLED->GPIONumber, AM_HAL_GPIO_OUTPUT); - - /* Enable the output driver, and set the output value to the LEDs "ON" state */ - am_hal_gpio_out_enable_bit_set(psLED->GPIONumber); - am_hal_gpio_out_bit_replace(psLED->GPIONumber, - psLED->Polarity & - AM_LED_POL_DIRECT_DRIVE_M); - } - else - { - /* Configure the pin as a tri-state GPIO */ - am_hal_gpio_pin_config(psLED->GPIONumber, AM_HAL_GPIO_3STATE); - - /* Disable the output driver, and set the output value to the LEDs "ON" state */ - am_hal_gpio_out_enable_bit_clear(psLED->GPIONumber); - am_hal_gpio_out_bit_replace(psLED->GPIONumber, - psLED->Polarity & - AM_LED_POL_DIRECT_DRIVE_M ); - } -} - -/** - * @brief Configures the necessary pins for an array of LEDs - * - * @param NumLEDs is the total number of LEDs in the array. - * - * This function configures the GPIOs for an array of LEDs. - * - * @return None. - */ -void rt_hw_led_array_init(rt_uint32_t NumLEDs) -{ - /* Loop through the list of LEDs, configuring each one individually */ - for ( int i = 0; i < NumLEDs; i++ ) - { - rt_hw_led_init(i); - } -} - -/** - * @brief Disables an array of LEDs - * - * @param NumLEDs is the total number of LEDs in the array. - * - * This function disables the GPIOs for an array of LEDs. - * - * @return None. - */ -void rt_hw_led_array_disable(rt_uint32_t NumLEDs) -{ - rt_hw_led_t *psLEDs = am_psLEDs; - - /* Loop through the list of LEDs, configuring each one individually */ - for ( int i = 0; i < NumLEDs; i++ ) - { - am_hal_gpio_pin_config((psLEDs + i)->GPIONumber, AM_HAL_GPIO_DISABLE); - } -} - -/** - * @brief Turns on the requested LED. - * - * @param LEDNum is the LED number for the light to turn on. - * - * This function turns on a single LED. - * - * @return None. - */ -void rt_hw_led_on(rt_uint32_t LEDNum) -{ - rt_hw_led_t *psLEDs = am_psLEDs; - - /* Handle Direct Drive Versus 3-State (with pull-up or no buffer) */ - if ( AM_LED_POL_DIRECT_DRIVE_M & psLEDs[LEDNum].Polarity ) - { - /* Set the output to the correct state for the LED */ - am_hal_gpio_out_bit_replace(psLEDs[LEDNum].GPIONumber, - psLEDs[LEDNum].Polarity & - AM_LED_POL_POLARITY_M ); - } - else - { - /* Turn on the output driver for the LED */ - am_hal_gpio_out_enable_bit_set(psLEDs[LEDNum].GPIONumber); - } -} - -/** - * @brief Turns off the requested LED. - * - * @param LEDNum is the LED number for the light to turn off. - * - * This function turns off a single LED. - * - * @return None. - */ -void rt_hw_led_off(rt_uint32_t LEDNum) -{ - rt_hw_led_t *psLEDs = am_psLEDs; - - /* Handle Direct Drive Versus 3-State (with pull-up or no buffer) */ - if ( AM_LED_POL_DIRECT_DRIVE_M & psLEDs[LEDNum].Polarity ) - { - /* Set the output to the correct state for the LED */ - am_hal_gpio_out_bit_replace(psLEDs[LEDNum].GPIONumber, - !(psLEDs[LEDNum].Polarity & - AM_LED_POL_POLARITY_M) ); - } - else - { - /* Turn off the output driver for the LED */ - am_hal_gpio_out_enable_bit_clear(psLEDs[LEDNum].GPIONumber); - } -} - -/** - * @brief Toggles the requested LED. - * - * @param LEDNum is the LED number for the light to toggle. - * - * This function toggles a single LED. - * - * @return None. - */ -void rt_hw_led_toggle(rt_uint32_t LEDNum) -{ - rt_hw_led_t *psLEDs = am_psLEDs; - - /* Handle Direct Drive Versus 3-State (with pull-up or no buffer) */ - if ( AM_LED_POL_DIRECT_DRIVE_M & psLEDs[LEDNum].Polarity ) - { - am_hal_gpio_out_bit_toggle(psLEDs[LEDNum].GPIONumber); - } - else - { - /* Check to see if the LED pin is enabled */ - if ( am_hal_gpio_out_enable_bit_get(psLEDs[LEDNum].GPIONumber) ) - { - /* If it was enabled, turn if off */ - am_hal_gpio_out_enable_bit_clear(psLEDs[LEDNum].GPIONumber); - } - else - { - /* If it was not enabled, turn if on */ - am_hal_gpio_out_enable_bit_set(psLEDs[LEDNum].GPIONumber); - } - } -} - -/** - * @brief Gets the state of the requested LED. - * - * @param LEDNum is the LED to check. - * - * This function checks the state of a single LED. - * - * @return 1(true) if the LED is on. - */ -int rt_hw_led_get(rt_uint32_t LEDNum) -{ - rt_hw_led_t *psLEDs = am_psLEDs; - - /* Handle Direct Drive Versus 3-State (with pull-up or no buffer) */ - if ( AM_LED_POL_DIRECT_DRIVE_M & psLEDs[LEDNum].Polarity ) - { - /* Mask to the GPIO bit position for this GPIO number */ - uint64_t ui64Mask = 0x01l << psLEDs[LEDNum].GPIONumber; - - /* Extract the state of this bit and return it */ - return !!(am_hal_gpio_input_read() & ui64Mask); - } - else - { - return am_hal_gpio_out_enable_bit_get( - psLEDs[LEDNum].GPIONumber); - } -} - -/** - * @brief Display a binary value using LEDs. - * - * @param NumLEDs is the number of LEDs in the array. - * @param Value is the value to display on the LEDs. - * - * This function displays a value in binary across an array of LEDs. - * - * @return None. - */ -void rt_hw_led_array_out(rt_uint32_t NumLEDs, rt_uint32_t Value) -{ - for ( int i = 0; i < NumLEDs; i++ ) - { - if ( Value & (1 << i) ) - { - rt_hw_led_on(i); - } - else - { - rt_hw_led_off(i); - } - } -} - -#ifdef RT_USING_FINSH -#include -static rt_uint8_t led_inited = 0; -void led(rt_uint32_t led, rt_uint32_t value) -{ - /* init led configuration if it's not inited. */ - if (!led_inited) - { -// rt_hw_led_init(0); -// rt_hw_led_init(1); - led_inited = 1; - } - - if ( led == 0 ) - { - /* set led status */ - switch (value) - { - case 0: - rt_hw_led_off(0); - break; - case 1: - rt_hw_led_on(0); - break; - default: - break; - } - } - - if ( led == 1 ) - { - /* set led status */ - switch (value) - { - case 0: - rt_hw_led_off(1); - break; - case 1: - rt_hw_led_on(1); - break; - default: - break; - } - } -} -FINSH_FUNCTION_EXPORT(led, set led[0 - 1] on[1] or off[0].) -#endif - -/*@}*/ diff --git a/bsp/apollo2/board/hw_led.h b/bsp/apollo2/board/hw_led.h deleted file mode 100644 index 8f954a7705..0000000000 --- a/bsp/apollo2/board/hw_led.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * File : hw_led.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2017, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2017-09-14 Haley the first version - */ - -#ifndef __HW_LED_H -#define __HW_LED_H - -#include - -/** - * @brief LED polarity macros - * - */ -#define AM_LED_POL_POLARITY_M 0x1 -#define AM_LED_ON_HIGH 0x1 -#define AM_LED_ON_LOW 0x0 - -/** - * @brief LED direct drive indicator macro - * Or this in with the polarity value to use the GPIO DATA register instead of - * the GPIO DATA ENABLE register to directly drive an LED buffer. - */ -#define AM_LED_POL_DIRECT_DRIVE_M 0x2 - - -/** - * @brief Structure for keeping track of LEDs - * - */ -typedef struct -{ - rt_uint32_t GPIONumber; - rt_uint32_t Polarity; -} -rt_hw_led_t; - -/** - * @brief External function definitions - * - */ -void rt_hw_led_init(rt_uint32_t LEDNum); -void rt_hw_led_array_init(rt_uint32_t NumLEDs); -void rt_hw_led_array_disable(rt_uint32_t NumLEDs); -void rt_hw_led_on(rt_uint32_t LEDNum); -void rt_hw_led_off(rt_uint32_t LEDNum); -void rt_hw_led_toggle(rt_uint32_t LEDNum); -int rt_hw_led_get(rt_uint32_t LEDNum); -void rt_hw_led_array_out(rt_uint32_t NumLEDs, rt_uint32_t Value); - -#endif // __HW_LED_H diff --git a/bsp/apollo2/board/hw_uart.h b/bsp/apollo2/board/hw_uart.h deleted file mode 100644 index afef169804..0000000000 --- a/bsp/apollo2/board/hw_uart.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * File : hw_uart.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2017, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2017-09-14 Haley the first version - */ - -#ifndef __HW_UART_H_ -#define __HW_UART_H_ - -#include - -void rt_hw_uart_init(void); -void rt_hw_uart_send_string(char *pcString); - -#endif // __HW_UART_H_ diff --git a/bsp/apollo2/board/led.c b/bsp/apollo2/board/led.c new file mode 100644 index 0000000000..bb8d1e1532 --- /dev/null +++ b/bsp/apollo2/board/led.c @@ -0,0 +1,152 @@ +/* + * File :_led.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-09-14 Haley the first version + */ + +#include +#include +#include "am_mcu_apollo.h" +#include "board.h" + +#define AM_GPIO_LED0 46 +#define AM_GPIO_LED1 47 +#define AM_GPIO_LED2 48 +#define AM_GPIO_LED3 49 + +/** + * @brief Turns on the requested LED. + * + * @param LEDNum is the LED number for the light to turn on. + * + * This function turns on a single LED. + * + * @return None. + */ +void rt_hw_led_on(rt_uint8_t LEDNum) +{ + if(LEDNum == 0) + rt_pin_write(AM_GPIO_LED0, PIN_LOW); + + else if(LEDNum == 1) + rt_pin_write(AM_GPIO_LED1, PIN_LOW); + + else if(LEDNum == 2) + rt_pin_write(AM_GPIO_LED2, PIN_LOW); + + else if(LEDNum == 3) + rt_pin_write(AM_GPIO_LED3, PIN_LOW); +} + +/** + * @brief Turns off the requested LED. + * + * @param LEDNum is the LED number for the light to turn off. + * + * This function turns off a single LED. + * + * @return None. + */ +void rt_hw_led_off(rt_uint8_t LEDNum) +{ + if(LEDNum == 0) + rt_pin_write(AM_GPIO_LED0, PIN_HIGH); + + else if(LEDNum == 1) + rt_pin_write(AM_GPIO_LED1, PIN_HIGH); + + else if(LEDNum == 2) + rt_pin_write(AM_GPIO_LED2, PIN_HIGH); + + else if(LEDNum == 3) + rt_pin_write(AM_GPIO_LED3, PIN_HIGH); +} + +/** + * @brief Configures the necessary pins for an array of LEDs + * + * @param None. + * + * This function configures a GPIO to drive an LED in a low-power way. + * + * @return None. + */ +int rt_hw_led_init(void) +{ +#if defined(RT_USING_LED0) + /* config led */ + rt_pin_mode(AM_GPIO_LED0, PIN_MODE_OUTPUT); + + /* turns off the led */ + rt_hw_led_off(0); +#endif /* RT_USING_LED0 */ + +#if defined(RT_USING_LED1) + /* config led */ + rt_pin_mode(AM_GPIO_LED1, PIN_MODE_OUTPUT); + + /* turns off the led */ + rt_hw_led_off(1); +#endif /* RT_USING_LED1 */ + +#if defined(RT_USING_LED2) + /* config led */ + rt_pin_mode(AM_GPIO_LED2, PIN_MODE_OUTPUT); + + /* turns off the led */ + rt_hw_led_off(2); +#endif /* RT_USING_LED0 */ + +#if defined(RT_USING_LED3) + /* config led */ + rt_pin_mode(AM_GPIO_LED3, PIN_MODE_OUTPUT); + + /* turns off the led */ + rt_hw_led_off(3); +#endif /* RT_USING_LED1 */ + + return 0; +} +#ifdef RT_USING_PIN +INIT_BOARD_EXPORT(rt_hw_led_init); +#endif + +#ifdef RT_USING_FINSH +#include +void led(rt_uint32_t led, rt_uint32_t state) +{ + /* set led status */ + switch (state) + { + case 0: + rt_hw_led_off(led); + break; + case 1: + rt_hw_led_on(led); + break; + default: + break; + } +} +FINSH_FUNCTION_EXPORT(led, turn led (0 - 3) on (1) or off (0).) +#endif + +/*@}*/ diff --git a/bsp/apollo2/board/led.h b/bsp/apollo2/board/led.h new file mode 100644 index 0000000000..e080e250cb --- /dev/null +++ b/bsp/apollo2/board/led.h @@ -0,0 +1,38 @@ +/* + * File : led.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-09-14 Haley the first version + */ + +#ifndef __HW_LED_H +#define __HW_LED_H + +#include + +/** + * @brief External function definitions + * + */ +void rt_hw_led_init(void); +void rt_hw_led_on(rt_uint8_t LEDNum); +void rt_hw_led_off(rt_uint8_t LEDNum); + +#endif // __HW_LED_H diff --git a/bsp/apollo2/board/hw_uart.c b/bsp/apollo2/board/uart.c similarity index 52% rename from bsp/apollo2/board/hw_uart.c rename to bsp/apollo2/board/uart.c index d1fa7af771..80a8f98d1d 100644 --- a/bsp/apollo2/board/hw_uart.c +++ b/bsp/apollo2/board/uart.c @@ -1,21 +1,30 @@ /* - * File : hw_uart.c + * File : uart.c * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2017, RT-Thread Development Team + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes * 2017-09-15 Haley the first version */ -#include "am_mcu_apollo.h" -#include "hw_uart.h" -#include "board.h" #include +#include "am_mcu_apollo.h" +#include "board.h" /* USART0 */ #define AM_UART0_INST 0 @@ -37,7 +46,7 @@ struct am_uart { uint32_t uart_device; - uint32_t uart_interrupt; + uint32_t uart_interrupt; }; /** @@ -70,17 +79,17 @@ static void rt_hw_uart_enable(struct am_uart* uart) /* Enable the UART */ am_hal_uart_enable(uart->uart_device); -#if defined(RT_USING_UART0) +#if defined(RT_USING_UART0) /* Make sure the UART RX and TX pins are enabled */ - am_hal_gpio_pin_config(UART0_GPIO_TX, UART0_GPIO_CFG_TX); - am_hal_gpio_pin_config(UART0_GPIO_RX, UART0_GPIO_CFG_RX | AM_HAL_GPIO_PULL12K); -#endif /* RT_USING_UART0 */ - -#if defined(RT_USING_UART1) + am_hal_gpio_pin_config(UART0_GPIO_TX, UART0_GPIO_CFG_TX); + am_hal_gpio_pin_config(UART0_GPIO_RX, UART0_GPIO_CFG_RX | AM_HAL_GPIO_PULL12K); +#endif /* RT_USING_UART0 */ + +#if defined(RT_USING_UART1) /* Make sure the UART RX and TX pins are enabled */ - am_hal_gpio_pin_config(UART1_GPIO_TX, UART1_GPIO_CFG_TX); - am_hal_gpio_pin_config(UART1_GPIO_RX, UART1_GPIO_CFG_RX | AM_HAL_GPIO_PULL12K); -#endif /* RT_USING_UART1 */ + am_hal_gpio_pin_config(UART1_GPIO_TX, UART1_GPIO_CFG_TX); + am_hal_gpio_pin_config(UART1_GPIO_RX, UART1_GPIO_CFG_RX | AM_HAL_GPIO_PULL12K); +#endif /* RT_USING_UART1 */ } /** @@ -94,26 +103,26 @@ static void rt_hw_uart_enable(struct am_uart* uart) */ static void rt_hw_uart_disable(struct am_uart* uart) { - /* Clear all interrupts before sleeping as having a pending UART interrupt burns power */ - am_hal_uart_int_clear(uart->uart_device, 0xFFFFFFFF); + /* Clear all interrupts before sleeping as having a pending UART interrupt burns power */ + am_hal_uart_int_clear(uart->uart_device, 0xFFFFFFFF); - /* Disable the UART */ - am_hal_uart_disable(uart->uart_device); - -#if defined(RT_USING_UART0) + /* Disable the UART */ + am_hal_uart_disable(uart->uart_device); + +#if defined(RT_USING_UART0) /* Disable the UART pins */ - am_hal_gpio_pin_config(UART0_GPIO_TX, AM_HAL_PIN_DISABLE); - am_hal_gpio_pin_config(UART0_GPIO_RX, AM_HAL_PIN_DISABLE); -#endif /* RT_USING_UART0 */ - -#if defined(RT_USING_UART1) + am_hal_gpio_pin_config(UART0_GPIO_TX, AM_HAL_PIN_DISABLE); + am_hal_gpio_pin_config(UART0_GPIO_RX, AM_HAL_PIN_DISABLE); +#endif /* RT_USING_UART0 */ + +#if defined(RT_USING_UART1) /* Disable the UART pins */ - am_hal_gpio_pin_config(UART1_GPIO_TX, AM_HAL_PIN_DISABLE); - am_hal_gpio_pin_config(UART1_GPIO_RX, AM_HAL_PIN_DISABLE); -#endif /* RT_USING_UART1 */ - - /* Disable the UART clock */ - am_hal_uart_clock_disable(uart->uart_device); + am_hal_gpio_pin_config(UART1_GPIO_TX, AM_HAL_PIN_DISABLE); + am_hal_gpio_pin_config(UART1_GPIO_RX, AM_HAL_PIN_DISABLE); +#endif /* RT_USING_UART1 */ + + /* Disable the UART clock */ + am_hal_uart_clock_disable(uart->uart_device); } /** @@ -129,9 +138,9 @@ static void rt_hw_uart_disable(struct am_uart* uart) void rt_hw_uart_send_string(char *pcString) { am_hal_uart_string_transmit_polled(AM_UART0_INST, pcString); - - /* Wait until busy bit clears to make sure UART fully transmitted last byte */ - while ( am_hal_uart_flags_get(AM_UART0_INST) & AM_HAL_UART_FR_BUSY ); + + /* Wait until busy bit clears to make sure UART fully transmitted last byte */ + while ( am_hal_uart_flags_get(AM_UART0_INST) & AM_HAL_UART_FR_BUSY ); } static rt_err_t am_configure(struct rt_serial_device *serial, struct serial_configure *cfg) @@ -141,29 +150,29 @@ static rt_err_t am_configure(struct rt_serial_device *serial, struct serial_conf RT_ASSERT(serial != RT_NULL); RT_ASSERT(cfg != RT_NULL); - uart = (struct am_uart *)serial->parent.user_data; + uart = (struct am_uart *)serial->parent.user_data; + + RT_ASSERT(uart != RT_NULL); + + /* Get the configure */ + g_sUartConfig.ui32BaudRate = cfg->baud_rate; + g_sUartConfig.ui32DataBits = cfg->data_bits; - RT_ASSERT(uart != RT_NULL); - - /* Get the configure */ - g_sUartConfig.ui32BaudRate = cfg->baud_rate; - g_sUartConfig.ui32DataBits = cfg->data_bits; - if (cfg->stop_bits == STOP_BITS_1) g_sUartConfig.bTwoStopBits = false; else if (cfg->stop_bits == STOP_BITS_2) g_sUartConfig.bTwoStopBits = true; - g_sUartConfig.ui32Parity = cfg->parity; - g_sUartConfig.ui32FlowCtrl = AM_HAL_UART_PARITY_NONE; - + g_sUartConfig.ui32Parity = cfg->parity; + g_sUartConfig.ui32FlowCtrl = AM_HAL_UART_PARITY_NONE; + /* Configure the UART */ am_hal_uart_config(uart->uart_device, &g_sUartConfig); /* Enable the UART */ - am_hal_uart_enable(uart->uart_device); - - return RT_EOK; + am_hal_uart_enable(uart->uart_device); + + return RT_EOK; } static rt_err_t am_control(struct rt_serial_device *serial, int cmd, void *arg) @@ -174,24 +183,24 @@ static rt_err_t am_control(struct rt_serial_device *serial, int cmd, void *arg) RT_ASSERT(serial != RT_NULL); uart = (struct am_uart *)serial->parent.user_data; - RT_ASSERT(uart != RT_NULL); - + RT_ASSERT(uart != RT_NULL); + switch (cmd) { /* disable interrupt */ - case RT_DEVICE_CTRL_CLR_INT: - rt_hw_uart_disable(uart); - break; - /* enable interrupt */ - case RT_DEVICE_CTRL_SET_INT: - rt_hw_uart_enable(uart); - break; - /* UART config */ - case RT_DEVICE_CTRL_CONFIG : - break; + case RT_DEVICE_CTRL_CLR_INT: + rt_hw_uart_disable(uart); + break; + /* enable interrupt */ + case RT_DEVICE_CTRL_SET_INT: + rt_hw_uart_enable(uart); + break; + /* UART config */ + case RT_DEVICE_CTRL_CONFIG : + break; } - - return RT_EOK; + + return RT_EOK; } static int am_putc(struct rt_serial_device *serial, char c) @@ -200,33 +209,33 @@ static int am_putc(struct rt_serial_device *serial, char c) RT_ASSERT(serial != RT_NULL); uart = (struct am_uart *)serial->parent.user_data; - - RT_ASSERT(uart != RT_NULL); - - am_hal_uart_char_transmit_polled(uart->uart_device, c); - - return 1; + + RT_ASSERT(uart != RT_NULL); + + am_hal_uart_char_transmit_polled(uart->uart_device, c); + + return 1; } - + static int am_getc(struct rt_serial_device *serial) { - char c; - int ch; - struct am_uart* uart; - - RT_ASSERT(serial != RT_NULL); + char c; + int ch; + struct am_uart* uart; + + RT_ASSERT(serial != RT_NULL); uart = (struct am_uart *)serial->parent.user_data; - RT_ASSERT(uart != RT_NULL); - + RT_ASSERT(uart != RT_NULL); + ch = -1; - if (am_hal_uart_flags_get(uart->uart_device) & AM_HAL_UART_FR_RX_FULL) + if ((am_hal_uart_flags_get(uart->uart_device) & AM_HAL_UART_FR_RX_EMPTY) == 0) { - am_hal_uart_char_receive_polled(uart->uart_device, &c); - ch = c & 0xff; + am_hal_uart_char_receive_polled(uart->uart_device, &c); + ch = c & 0xff; } - - return ch; + + return ch; } /** @@ -236,35 +245,35 @@ static int am_getc(struct rt_serial_device *serial) */ static void uart_isr(struct rt_serial_device *serial) { - uint32_t status; - - RT_ASSERT(serial != RT_NULL); - struct am_uart *uart = (struct am_uart *) serial->parent.user_data; - - RT_ASSERT(uart != RT_NULL); + uint32_t status; + + RT_ASSERT(serial != RT_NULL); + struct am_uart *uart = (struct am_uart *) serial->parent.user_data; + + RT_ASSERT(uart != RT_NULL); /* Read the interrupt status */ - status = am_hal_uart_int_status_get(uart->uart_device, false); - - //rt_kprintf("status is %d\r\n", status); - - /* Clear the UART interrupt */ - am_hal_uart_int_clear(uart->uart_device, status); + status = am_hal_uart_int_status_get(uart->uart_device, false); + + //rt_kprintf("status is %d\r\n", status); + + /* Clear the UART interrupt */ + am_hal_uart_int_clear(uart->uart_device, status); if (status & (AM_HAL_UART_INT_RX_TMOUT)) { - rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_TIMEOUT); + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } if (status & AM_HAL_UART_INT_RX) - { - rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); - } + { + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); + } - if (status & AM_HAL_UART_INT_TX) - { - //rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE); - } + if (status & AM_HAL_UART_INT_TX) + { + // rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE); + } } static const struct rt_uart_ops am_uart_ops = @@ -280,7 +289,7 @@ static const struct rt_uart_ops am_uart_ops = struct am_uart uart0 = { AM_UART0_INST, - AM_HAL_INTERRUPT_UART0 + AM_HAL_INTERRUPT_UART0 }; static struct rt_serial_device serial0; @@ -301,7 +310,7 @@ void am_uart0_isr(void) struct am_uart uart1 = { AM_UART1_INST, - AM_HAL_INTERRUPT_UART1 + AM_HAL_INTERRUPT_UART1 }; static struct rt_serial_device serial1; @@ -309,7 +318,7 @@ void am_uart1_isr(void) { /* enter interrupt */ rt_interrupt_enter(); - + uart_isr(&serial1); /* leave interrupt */ @@ -319,17 +328,17 @@ void am_uart1_isr(void) static void GPIO_Configuration(void) { -#if defined(RT_USING_UART0) +#if defined(RT_USING_UART0) /* Make sure the UART RX and TX pins are enabled */ - am_hal_gpio_pin_config(UART0_GPIO_TX, UART0_GPIO_CFG_TX); - am_hal_gpio_pin_config(UART0_GPIO_RX, UART0_GPIO_CFG_RX | AM_HAL_GPIO_PULL12K); -#endif /* RT_USING_UART0 */ - -#if defined(RT_USING_UART1) + am_hal_gpio_pin_config(UART0_GPIO_TX, UART0_GPIO_CFG_TX); + am_hal_gpio_pin_config(UART0_GPIO_RX, UART0_GPIO_CFG_RX | AM_HAL_GPIO_PULL12K); +#endif /* RT_USING_UART0 */ + +#if defined(RT_USING_UART1) /* Make sure the UART RX and TX pins are enabled */ - am_hal_gpio_pin_config(UART1_GPIO_TX, UART1_GPIO_CFG_TX); - am_hal_gpio_pin_config(UART1_GPIO_RX, UART1_GPIO_CFG_RX | AM_HAL_GPIO_PULL12K); -#endif /* RT_USING_UART1 */ + am_hal_gpio_pin_config(UART1_GPIO_TX, UART1_GPIO_CFG_TX); + am_hal_gpio_pin_config(UART1_GPIO_RX, UART1_GPIO_CFG_RX | AM_HAL_GPIO_PULL12K); +#endif /* RT_USING_UART1 */ } static void RCC_Configuration(struct am_uart* uart) @@ -341,26 +350,25 @@ static void RCC_Configuration(struct am_uart* uart) am_hal_uart_clock_enable(uart->uart_device); /* Disable the UART before configuring it */ - am_hal_uart_disable(uart->uart_device); - + am_hal_uart_disable(uart->uart_device); + /* Configure the UART */ - am_hal_uart_config(uart->uart_device, &g_sUartConfig); - + am_hal_uart_config(uart->uart_device, &g_sUartConfig); + /* Enable the UART */ - am_hal_uart_enable(uart->uart_device); + am_hal_uart_enable(uart->uart_device); /* Enable the UART FIFO */ - //am_hal_uart_fifo_config(uart->uart_device, AM_HAL_UART_TX_FIFO_1_2 | AM_HAL_UART_RX_FIFO_1_2); + am_hal_uart_fifo_config(uart->uart_device, AM_HAL_UART_TX_FIFO_1_2 | AM_HAL_UART_RX_FIFO_1_2); } static void NVIC_Configuration(struct am_uart* uart) { - /* Enable interrupts */ - am_hal_uart_int_enable(uart->uart_device, AM_HAL_UART_INT_RX); - - /* Enable the uart interrupt in the NVIC */ - am_hal_interrupt_enable(uart->uart_interrupt); - am_hal_uart_int_clear(uart->uart_device, 0xFFFFFFFF); + /* Enable interrupts */ + am_hal_uart_int_enable(uart->uart_device, AM_HAL_UART_INT_RX_TMOUT | AM_HAL_UART_INT_RX); + + /* Enable the uart interrupt in the NVIC */ + am_hal_interrupt_enable(uart->uart_interrupt); } /** @@ -373,40 +381,40 @@ static void NVIC_Configuration(struct am_uart* uart) void rt_hw_uart_init(void) { struct am_uart* uart; - struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; GPIO_Configuration(); - + #if defined(RT_USING_UART0) uart = &uart0; config.baud_rate = BAUD_RATE_115200; - RCC_Configuration(uart); - NVIC_Configuration(uart); - + RCC_Configuration(uart); + NVIC_Configuration(uart); + serial0.ops = &am_uart_ops; - serial0.config = config; - + serial0.config = config; + /* register UART1 device */ rt_hw_serial_register(&serial0, "uart0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | - RT_DEVICE_FLAG_INT_TX, uart); + RT_DEVICE_FLAG_INT_TX, uart); #endif /* RT_USING_UART0 */ #if defined(RT_USING_UART1) uart = &uart1; config.baud_rate = BAUD_RATE_115200; - RCC_Configuration(uart); - NVIC_Configuration(uart); - + RCC_Configuration(uart); + NVIC_Configuration(uart); + serial1.ops = &am_uart_ops; - serial1.config = config; - + serial1.config = config; + /* register UART1 device */ rt_hw_serial_register(&serial1, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | - RT_DEVICE_FLAG_INT_TX, uart); + RT_DEVICE_FLAG_INT_TX, uart); #endif /* RT_USING_UART1 */ } diff --git a/bsp/apollo2/board/uart.h b/bsp/apollo2/board/uart.h new file mode 100644 index 0000000000..49fff8a9f7 --- /dev/null +++ b/bsp/apollo2/board/uart.h @@ -0,0 +1,30 @@ +/* + * File : uart.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-09-14 Haley the first version + */ + +#ifndef __UART_H_ +#define __UART_H_ + +void rt_hw_uart_init(void); + +#endif // __UART_H_ From 026696789813cededdd0539dd84fea8f7a71602e Mon Sep 17 00:00:00 2001 From: lin <429426691@qq.com> Date: Mon, 18 Sep 2017 17:58:26 +0800 Subject: [PATCH 3/5] Add README.md file --- bsp/apollo2/README.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 bsp/apollo2/README.md diff --git a/bsp/apollo2/README.md b/bsp/apollo2/README.md new file mode 100644 index 0000000000..2b265d13aa --- /dev/null +++ b/bsp/apollo2/README.md @@ -0,0 +1,5 @@ +Apollo2 MCUÊÇ»ùÓÚAmbiq MicroµÄApollo MCU²úƷϵÁеĵڶþ´ú¿ØÖÆÆ÷¡£ +AmbiqʹÓÃרÀûÑÇãÐÖµ¹¦ÂÊÓÅ»¯¼¼Êõ£¨Subthreshold Power Optimized Technology£¬ SPOT£©Æ½Ì¨À´ÊµÏÖ¾ªÈ˵ŦºÄ½µµÍ£¬Æä¹¦ºÄͨ³£±ÈÐÔÄÜÏà½üµÄÆäËüMCU²úÆ·½µµÍ5ÖÁ10±¶¡£ +Apollo2 MCU²ÉÓÃ32λARM Cortex-M4F΢¿ØÖÆÆ÷£¬¼¯³ÉÁ˸ߴï1 MBµÄÉÁ´æºÍ256 KBµÄRAM£¬ÒÔÊÊÓ¦ÎÞÏßµçºÍ´«¸ÐÆ÷¿ªÏú£¬Í¬Ê±ÈÔÁôÓÐ×ã¹»µÄÓ¦ÓôúÂë¿Õ¼ä¡£ + +board info:Apollo2 Evaluation Board£¨http://ambiqmicro.com/apollo-ultra-low-power-mcu/apollo2-mcu-20170703/£© \ No newline at end of file From e8eaaed1fea72444d91012e24951669f818c123a Mon Sep 17 00:00:00 2001 From: lin <429426691@qq.com> Date: Wed, 20 Sep 2017 11:14:45 +0800 Subject: [PATCH 4/5] Modified fomat and add low power --- bsp/apollo2/README.md | 46 +++++++- bsp/apollo2/apollo2 evaluation board skt.jpg | Bin 0 -> 298028 bytes bsp/apollo2/applications/SConscript | 4 +- bsp/apollo2/applications/main.c | 4 +- bsp/apollo2/board/Sconscript | 4 +- bsp/apollo2/board/board.c | 111 ++++++++++++------- bsp/apollo2/board/board.h | 33 +++++- bsp/apollo2/board/led.c | 9 +- bsp/apollo2/rtconfig.h | 14 ++- 9 files changed, 170 insertions(+), 55 deletions(-) create mode 100644 bsp/apollo2/apollo2 evaluation board skt.jpg diff --git a/bsp/apollo2/README.md b/bsp/apollo2/README.md index 2b265d13aa..871cad2fb5 100644 --- a/bsp/apollo2/README.md +++ b/bsp/apollo2/README.md @@ -1,5 +1,45 @@ Apollo2 MCUÊÇ»ùÓÚAmbiq MicroµÄApollo MCU²úƷϵÁеĵڶþ´ú¿ØÖÆÆ÷¡£ -AmbiqʹÓÃרÀûÑÇãÐÖµ¹¦ÂÊÓÅ»¯¼¼Êõ£¨Subthreshold Power Optimized Technology£¬ SPOT£©Æ½Ì¨À´ÊµÏÖ¾ªÈ˵ŦºÄ½µµÍ£¬Æä¹¦ºÄͨ³£±ÈÐÔÄÜÏà½üµÄÆäËüMCU²úÆ·½µµÍ5ÖÁ10±¶¡£ -Apollo2 MCU²ÉÓÃ32λARM Cortex-M4F΢¿ØÖÆÆ÷£¬¼¯³ÉÁ˸ߴï1 MBµÄÉÁ´æºÍ256 KBµÄRAM£¬ÒÔÊÊÓ¦ÎÞÏßµçºÍ´«¸ÐÆ÷¿ªÏú£¬Í¬Ê±ÈÔÁôÓÐ×ã¹»µÄÓ¦ÓôúÂë¿Õ¼ä¡£ +AmbiqʹÓÃרÀûÑÇãÐÖµ¹¦ÂÊÓÅ»¯¼¼Êõ£¨Subthreshold Power Optimized Technology£¬ SPOT£©Æ½Ì¨À´ÊµÏÖ¾ªÈ˵ŦºÄ½µµÍ£¬Æä¹¦ºÄͨ³£±ÈÐÔÄÜÏà½üµÄÆäËüMCU²úÆ·½µµÍ5ÖÁ10±¶¡£ +Apollo2 MCU²ÉÓÃ32λARM Cortex-M4F΢¿ØÖÆÆ÷£¬¼¯³ÉÁ˸ߴï1 MBµÄÉÁ´æºÍ256 KBµÄRAM£¬ÒÔÊÊÓ¦ÎÞÏßµçºÍ´«¸ÐÆ÷¿ªÏú£¬Í¬Ê±ÈÔÁôÓÐ×ã¹»µÄÓ¦ÓôúÂë¿Õ¼ä¡£¸Ã΢¿ØÖÆÆ÷»¹°üÀ¨´®ÐÐÖ÷»úºÍUART¶Ë¿Ú£¬ÓÃÓÚÓëÎÞÏßµçºÍ´«¸ÐÆ÷ͨÐÅ£¬°üÀ¨¼ÓËٶȼƣ¬ÍÓÂÝÒǺʹÅÁ¦¼Æ¡£ -board info:Apollo2 Evaluation Board£¨http://ambiqmicro.com/apollo-ultra-low-power-mcu/apollo2-mcu-20170703/£© \ No newline at end of file +Features +Ultra-low supply current + 10 ¦ÌA/MHz executing from flash at 3.3 V + 10 ¦ÌA/MHz executing from RAM at 3.3 V + +High-performance ARM Cortex-M4 Processor + Up to 48 MHz clock frequency + Floating point unit + Memory protection unit + Wake-up interrupt controller with 32 interrupts + +Ultra-low power memory: + Up to 1 MB of flash memory for code/data + Up to 256 KB of low leakage RAM for code/data + 16kB 1 or 2-way Associative Cache + +Ultra-low power interface for off-chip sensors: + 14 bit, 15-channel, up to 1.2 MS/s ADC + Voltage Comparator + Temperature sensor with +/-2C accuracy + +Flexible serial peripherals: + 6x I2C/SPI master for communication with sensors,?radios, and other peripherals + 1x I2C/SPI slave for host communications + 2x UART for communication with peripherals and?legacy devices + PDM for mono and stereo audio microphone + +Rich set of clock sources: + 32.768 kHz XTAL oscillator + Low frequency RC oscillator ¨C 1.024 kHz + High frequency RC oscillator ¨C 48 MHz + RTC based on Ambiq¡¯s AM08X5/18X5 families + +Wide operating range: 1.8-3.6 V, ¨C40 to 85¡ãC + +Compact package options: + 2.5 x 2.5 mm 49-pin CSP with 34 GPIO + 4.5 x 4.5 mm 64-pin BGA with 50 GPIO + +Board info + Apollo2 Evaluation Board£¨http://ambiqmicro.com/apollo-ultra-low-power-mcu/apollo2-mcu-20170703/£© \ No newline at end of file diff --git a/bsp/apollo2/apollo2 evaluation board skt.jpg b/bsp/apollo2/apollo2 evaluation board skt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..67bf9c23ffcbc272dbe949d8a13c8c4052abec79 GIT binary patch literal 298028 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

3Q3>cqo}cTX0LxP4Ggq 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

<= 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

r3raQ z=q>fNQ){fo-%F%98hu97@?m_~DW5I;rFX+#+&;-ZASi2X;z8m2>@i)3tDR>`+xdP@ z&v4gmy>(6s{M+}Vdz&OcFRZN^A5n6c;zRcMaE7PfP(=~Ds?CG|(dk+a4}xcZ2*lal zEckpmW2WCVfy_;)W|QrapdzoC^r0v)rhusE{@M(`=OMG3Y-e{2 zooqZmOeb)!TpcQ|wt)t{bVb+R3k&VPuk2)EZ|vm8RUUL_iWOqCK=0xM(H2<{zf;P3 z7gqfYzB=`1-;MJvTW9X9N>mE3yobjkXg$m&E4(*-N$B~;f^WB(xKeJN!E4Os705;; zG4ix>HxpqIh&G<6e7x_w4oXi;iMf8>^p{6L+53^f#+rT1G!p+1^rHQNCbf(piKILB(c=Ec-?DW=2G#<`IxZm1naeV-=Y(`_f zmZ%)YRh?bMBi0XX9f)5g4GNW*|5`D1@nI!lsHE+0Fo%I){yW7@quTb~nU)97%z~EI zw;+x9pjw4XDPJ2CB`;?mZK*fQpO`E>4iM{R6iNJpZgDGLNPsR-R`F>A&^K1P34_DF zWo1!hQP;hpYLVVgf+|upv^%TJpG?ji0=e_}Mg;ce60mc633mg)VSG;;2wAxB0%NA3 zDqXhsKAWBkB*D{|n@_)V=?5v^>{{$D>o>L&T5$49|4cIqC%-Gw$PlCb-RUE_hrZ?)V&dMI~nyOu3^J@~}L=+$?y=WX;d$sB#X@y}`bBc)CqE zDQ^h)eVuY8$DNS|B<$V8(G<&0u7@5d>4zim?8MnTQ~h&e(K&ZjP{bp`EEN{I|nFC zVGUG%n*M!tTm89%c_K4vJrYav*nWvtx@2kCrh0NdgNQlHC_w@{B5V;}=&N9aU&3~- zj#6&>JEf!7Z;C5s=g_@JELe^hIyV^-;6KwZI&31YG&MRk6XJXjev#NEam=FJW5PT6 ze^>gmD%@#Nava}yHC!F~+Q^5S1hlBbGZM@JRQJHTv?9+ykNB@_RxY99dIUbY?gN4n z_TU{l{1nPjGLw9(2XbHO(;9Au7#awym&qcRJMIGjA=bzE$i75U`*x11Y1<^IXAb|a zNxYraqgSdTJk{o6%UIsmyJlM0luK?x`3fuCYxQ1=2CDTjbcebyx2e#~4~cPY{rLU! z*brS#G7%(HB*nXF+}kJZKcag5b|~&lZUTF3{?yge_hXD7{jDC~P8~_%5Bnn?nMa^# zaGh8^hRT&?D%$E3Cm(rp$-}t>Qi`9CY51DTL)Z^qmp??Y0Ldos<^`79mC&AANK`VT^>bWC}t8ei%Ln$T} z@(RjA`JkWH`^4EEmUlLp7(;w$x52zdz8WTZIy(qo}}%n?et6} zG^nUcy75e%d-mVj?Uw4p-27ttWy37X2;528>k)L_QonKV{jK7JQX2a_^{WSXnZ#Z! zNe?OZ-JbkS}NTV>SE56L*C3OC3$Jb!#tIyXtfpRNa zbPf$BC(WFL{gq006Mj_B|HE~=S4Z%$y)1h|-XhPO0Ks&Gf*)V0;?6J$sUgdDKs~40 z%{%Y!y{BJ;nSgW#+x;Z7&w6W&7Z*#X_5@eVu>0J5d`I{dAMUKzaDt;|t07k=V#=>g zYyX|Q-)nGp>xTCJs-P?U@+b`(qXEx!+FzOBKokxb(X24ASuiHNcQN+&HeAQ=+rQd0u$a3)E2L+? zU4-zkd~@K+OgZ)=ZXH|uUU-eEUkhC^fdxc$+#4^<9VO1Tqrpb8NFQC<%v zy0+Uu(!08dprvv%D)+D#awmL!m4Tz>`hDgwpHgoq;}hir8GDP(rn1jx3l z00x8aMkBn|XxSl6`CPAx{Q+U^__zYfq>KDLUC%MePR=o#U~nk}XJB5tUUVBZ8PIdG zFBsLnt`Bi+vpkKM&W|*#j?`+c$>^z;U;jbXCyccOH|Xte3I7uv_gy$XgI5d67K&AT z8u@kf>Y;7_LhW^K4kSH|mB}a9w2CsbOObsNZ0pJ-{^jPW?5{D=E@+ea*M|KyA6Py= zFrfvwNtRBc_OBPt*?b?+`wD#nU*pF}d0v<|I5%ww%nf;UV3g z>bLlN??bs7slt|&0Qy$F-t|Z>!R1!mMt#SMjbnNmR{T`m&n+%_L`c#wlfd)7F`mqz z!=^s|v%4;5aB54C+Xiq>DO&3P%;KlwH_GgJV8Qh76}-K}Z@a>Cwh@q@a#ej)?Oc*z zclJwR!9qdJ{SC%)b?f*0x6N{s7`5DSmFXgJIrIs4RiWD`s<%+l9`EWi#Xc42i?v20 zso85x+Dm7n2tL+zSH@M(&wPJ*#jQxt1=UmSz20NPCAA)@F|rU@Ki*2Lp0eoBq+*0q z@*B_q%pUGE0)-UHfqu5UOSG8MWN`7MmgDSE1?sw5+^^3y=cg5?enwpC&x@5s?jz2^ zh4sXBj0NWE^%5jTdFVg`HRd8PQN=nsad!!(?6A1Ri44wb`7=e@K&JBTTO&-I9`CB_ z8<8fjd9i%he4go%CyeTa%`t3HW-5d@1O4j%V-4ZZ_S{RC%EFYJjPk%=!B40iRX;aS z|3_4?^L($^rI&%orwrIa)u#+SGHvU6eO#2I*(V`g&c{-atkt~#S@1*@FyQF6kX84) zxmvM`m1ySgIPBkB?Uor-@FMd*RgeD-C!eWUP*D)7o76;6KfU~m>rg9h7}*E&@mIn) zM?P14)*={$=VpOtr8}x)eU}J751-HQifc@(`^q^QPK%!D$1JCu>nWQZa@d>An-BQY zNN`VO`Y;sx+5b_8)$iz-37)6Ew}beUT|C5)dbmP_MFf)fB|iI~lt=sVr{68-%W0*W z4;gfz@XpiSJ}zUNuSjYMak`%x>_PqEp6pT%Q`lHr07iWfss;f|vdF%EZL8l;ylsr~ zcZ^Pjp73O_EnIGnFtq2HBqMZ8Z5whIQ6ri9hZ%(ol*c8m^$@J&1NPSHP>I!`T{tSU zMngq33XN1Z4U$zwQr$Gj4aAIroF|6(Jc1zW{~FCeF5ggKR+#8?jp*98Z8~W<)%8Zn zpDE9%r-%C-$s0C5KHSz+4t)RArJyd&N_bdwu5U>G*i!Sl3>nJ>Ej63hAa85SewU%K z8^%46B^w_E6nb+ETEIy}F{M)!{#)t&2)1_l4B5;)BavAjWjE;{w)^+Cpvw z?qsICv`&2SU|y@p5xkcJx=aUWlwHK7{TpiV_7SI6kyHAyECAFj0T-4NB=49q^5z1V z{KiW_ZNcPilh{_>5{C=mNF$rh5qHue5EnZdW; z`Y6ws4lBJ*@<^BN#$2FP3o>a`pL8LdzPQDO_$NLrj>5Leh{i|cK8-+rW+{-aVn4X3 zx4*yT3EWoZ+M#YNiIL7osjV6p1HQwz-9&9kiZ0dvY@&u5XLD02BcYr?wa`?3z-}q;*w5~#1Dz>j4;7?(P+p1?d{~nW zVLJxC4KiWnJT(n!m2ukFmHaRh23hz2h!9&E!Wt8pDO+dRC9U+qNLIt2J-oSV(*`(_ zsAH@eWJbW5FQ5AiUrV`=G|5{3``$@>*;aBJ;xtg#?0|#kkWNNO!@;bxVb;2RO8;Y1 zTvN=g!*Xw$tWTDPO+YrSJYL?4VoJr($x*p+N5f)*7aEaAIqP}eI+nv7`26H=88MIM zG}d_|MpfjpJiaM`lj90&uapKY>DcXrFMik$T`r+fmFSO5lcw@W(h^FXgZJR(8*tcfSYfoS#(tq{(-k-iI`PIBsIvok!TOXPpjSqh4(Egb4(LuD~HwFmTrF`G! z!+tAB{1^A|;_<07J~G@3u$%-+`V%BoGir+ZkcufX4QbMb#lG%ZU(Q~RZ$oic5ljpU z^0!#CQF6;#6oCR`f$Ef3>}fYN@M+sSeY``#9=A|L9+tV|xQ%aaV?6^|smmDv3okv$KM$ZMlwLu?c-wEh3Eq2+(0K+ke@962gkd@Zzn85RLvZj6HA z)Vs^s? zg(6NpSy>>4T2I$~cp4?TnK!wwAo-lGv-3uqxHd;fnd~ulk9C@#~rDkn=Ln^;nDi^-<=uQm_N&u9|hbzti^eBchvgCio&8K z)6!R%V5B>}+)ZPKJ*0Q9=M%piu;f=-8(1YPxaIzY1^ifRBGltqAwdS?MKwm#S<*zZ zPN74Ea-U|2_ewq_k@W8+y*5S9>sR=QwF&XR zjkYpHE7H*sg(Zk5j}T|;?gd0(FtS7UKO!rDzps_hVFTExP|9jQ`^(^dKJ zFsbs&uO)nb6@b#`vDD%8n64kaZ{Gn2_gsUtfR7qe=S&N^rU)?2GM%%@$hXaTpm@Uu zh;VYuUwBfkYeSZkO^WxzSFRZk4=)gAkp`;NFFt<7t}9!p32rx*{$uTHv}6hd1B>ju zIg_9O4ctv({&vV5k;7yKuhkDCa4d(*DTm=63QJSu0ICz%^J4dnekbddY%Wgh=~4DL z72M@9qUcB1YlvIN(jE+0IS%v}@bzS|35Mpc1zvRsGM@|@Dq_gJoplj>R&D`4Zp@F*r3!uu zVM%T!@U&ewZf3o$CO};6nB!R*5Y4Q*U9ZzJaD=ib)&PgZv^}5t zRS~80)Zd{d!8T6eZIE|b!`;6Nk7+(@ z@`NM7=Aq{grXJ!luC;ao^7DdI&11aSP82rko~BUp21FfnZg~E=%rKF2G1*jVTf2yB z1v-KLZpA7B@<{|e={5(7)<;nnI!@)HH8KsXDkA>#D*8Fs-Lq5HoUUG|x|rWsmWUcw z8_Wv+!K5>Yl&{HSu^amY!100}K4MVEFy>C`L9$f|Rf=?!ku{<;upI4K5xjvzdj9X< z&VP=%-aE}aPizK@rXpADWqFHuT6}<1HD#2f1u4nDH~KElaJE+mHE1Dt9a;o2pi!&2 zalScE`*ZGq$1&!v!fZiA{)QA&!=Rywsj@erS}F)+PAF-1md^IhUslMWEgwE^?kg@Q zUfR20dohditx4X)8=V78ISy=Fq?t3IAc6!Z+<|LjM)k2I-MworPD8J?DRH9f`UO?F z!}MW-U*E5nrAD+d6=)&B-*tq9nrrZvl&e!eUymJhmpCr%kk;`2aUxW(ZzcARy5gs- zk zUAlvnIoD0<$|gG zqj?I~PdX41xFw9<8vRelwQL4SWiebdsm;lon-CK5j%Pqh4l6#q+4(YMU@+|IZP|82 z0&&Jzu&6-LTg!=L(X$kO>#=8bxuCHY5 z|0pfduxR^fFA9TLs9M{MClwh~d_-#3)$1#|)US$C1$(pXMw6El&Pj`E4Qu_Ee*q6< z9*7MGm7v-}xf!@0XTOcG#5y!!fgLF!PC-vck-kZLGYp+yDj$g5O8BF%^3ve}eR%8t z(U4FW`$8wUS|p=j`zpKzrG{0GFMy;ZK|F=hlWO(_pCWl4lO@zYZYRIl=!p+3iPY-f z;mY2$kL;Ld=h?zlf0a5QiOFRE;;=QoV9a6%48ON?6vurR*MNR&hoKCEYc}G8g(pvs zZu2Lw3+YKdkt}irrjGq}`cXYVX$W9SS{wZb`oFKUQ~WI$KZq43qmNDAEW5XBZv1m- z*yE4p$JhOW{(-XkM&BLg7ul~FiBvhOus1~NI*dhk)+29=Ag`{gf$g!aO%``;@lCY{ zwhtGJ))OUq{5jQPVm2FmOva7|wmk)vw{BrAR-qlE|Ab(E?I1=dBA5sNvT9QJgO4EH zqlv*Df%J(s0K>{-9L*2Qy7)qrA2`zm`Zd5=7I1WJ#3PY@EA=fWuA(ny#(ZhAGd zTWtL00|$w2ed*CFcpw_VEs1-B0?lcx#ie3q41nDSAoHp$zQ$@Nw{p>RAEPv0P9|zy zQ^m(}Ojzz2Q|0JnVB89z^@(0CYi3;hS&a ziL8!83jY{(*CKglDoC*%wRhVNJbssTCC6#@$?>Vrq)}v^UwRG8z1lV~ahwHJBfko_ zIX+fYz?=`;e^wII)v>jVTG%*oW0NtrsMX@IjVVIv99OJ=0xR!=ff-hxwWN9zNIH%> z4M#?%&t&p;XCb<J{ zM!B52-b{Kclms!uh?YY7gk0K#f3cre9m^HY%IlDcFyy%#)?vv)Z|Y%$R=0f2V_F&J zM46#PLGO;8n0Il4r>Y$xG`1MWQ12zC=C8SRm71un@OSs!yW+e~@g+l~>n`NxuE4Z) z{6}_kZ`Su%qZAgWkP%qo%quiu@pARKrB6Er9+~z1O&(J*zoFw#r{#N91X8?*Bc1J< zNsYa8kq%0je$N!+GbyW8-C`~~<6Oo>($*?ORuaJv?PIRK^4qS#I)Q)h0%vpdY_lBy;7JxSpY1J((^*3GZJ2}gRxZqF z#KG{z*YfgKh^q*9l&x34SF_m(T%#0BF@xtu>V`seCC5cufWVz*UU)8bC@qc{3tF%>}&q{N+PD;1LA^)J=!pO zBd`UweT%*!};#>xG{YvR00vf1H$QzFllmY3=R_y#%sWvFKB=w+3su>}!$3lGv_ z*UCluX`73IkcZ~dJBPkSC8R83oAJDNwwa?axF1}@8{pcL8%#^G+$(8%RLIO$!=Loz zukZU9KU!K&EO>O~GhBLE7WWmB?;p)>Y5Crn^S~(Po@LU)24(tw{(^bt8GV&5p-@U& z*h_zkzakuxfp+DMWz6tAQDKO+I=6Ly=Q#l5Z(bh8?{yyZ+cxFPNgaH{-y1vCi^_T& zXQ8CLrNVCR5}?vF#U?yt_$rchC?ZiDjWDoSArHQbW9iNku8M;Kc7q>|!PQW5l1`$+ zBFl1;g`aO$(sDjquNx6F*72T{+o(VX@J3mw1}#T$xlFfTTS6NADPrQ5r+0zC*8AIF z+GaM)Ia;l%(OGKv=`rdYo9k%N|EMjU$s;>C_@y;V%uQetT3c zdV3LUuFjL_7#JI&8@2gTi!;$KA)12X>>Ks@lj&+*D)oI_{=ATSo4@J5*;X8-p=PTT zp7PqTT1+Ls(4VWK-mO8Qev4dcJa`dE4!^N>^ce^sK7cW*&M30CKAx@#;y!skC7N~c z3-To8*<)vAk9wIQ09l+YA|Lb)@lT*@rP_4=Z^DU9#?DjepKBY5mE4w5wCGVcSH3bXz}{^8@EFXfu@* z?C+Gz#z}(@2H$Cc#0cHZH;zbTFi+xGcEwgFV(#7o5Pn2(XC{6Rr*5dvTutEvUU{B4#x8VIa7L3SH06edftmf z*Ui1^Ved^m<`Y}q>(CRA0og@dX!y4SIWOXfHrYPe<|qHX)o`Lu!kjUvlk z8NaXnG<|*V6($in$4gAQ8e`cQ{WhFHD*h=!;XDun?#iZjF|=}#7|vN-(T-d&ouSy- zwAAd*6by5)?zlx7?x6n=T||1^4FrtN8y8Xqw^`dOlJY;i2+7@J{tIEz31n5IG^zch zVi~+^04Bp5;gqm}Xv%O!M#viIt2HC;(;Araa(HcFTTusU8*)$kVN%e9rMwnrjx66N zYH^9E{otp>g=#DqQ%aUi~b8Mb>4ynk{*;ULAD6!fB_8Gri=RL^IUhhYMqNXS+h~Dw6hj zRJs{CB%d!u^1+4}v4^VOeI|;2SF_>7ad5SLc26{}46l^0lke>QbAQ51@@N$NTwCPJjV*!tzfzFy zg4-k;ZWQTmghtGVRR>7Nvu__)OFN}RneUQ!mL#;_xy?eZc!r2mz6FO*fgIw2+v)$2 zB|%D&oKQh$l*tRfn`GZVJ`3-1?Wg3#reBCgXV-~#9YrZ~RkcpSC5m=}pC;#J8*|L= z*LiZAl5vWR-Px8{NpJRLWRh;lu+hzvD$$TyGnynd-5y1-)Xtgn+%yO&v}747eJcnI~5?6L^c zJWTki!mAQ}t6kBwzpYlU>lqr%0H>>ZYw9!lQF6{o##Mw#Oa&Ac;CCR1jW8i(HG|P4 z5m1JHMGaQBA*b#$p6`#jCO5=Y>KUW8Wud@;D7(o0pWPL_)TD6C1<~G%ESAX-M}o_O zbA3d+ylqw8lKqoDkolqWsobIYWQYS3mOm%Z)kmr|K7U6#28*O6UC?*Cn@WJ9a^RZA zzS3G-G%10gI=j2dsmWeH?YZsy;W(}9U&f$FQ1xa8%G)gEM1L|rfh=9NpW6xfI<)U< z_7kq4d;aG|WNyklYIjLbHqL~HJl{P4)sUy2^DmD#co^B}V)_J3O9SZI65nd1SSTQRG%gN;Z$V@3y%;Vh*-smJ%qVyjev)EUpTdJ?iot8Lb1 zV7_V|$-3di6;05x&RRl#qF6`-ZAh{m+?`OEi{&p3S!1KivuHY8&JljF4Ir(At*g#` z-bikKJ%1U3d5O5y8g@R7o%zjkm*YaL*EGAgo}fykqRQJz&znG^A-xvi%Uk^hO=ko_ zlrvEp*Ke&k+mqhG;Xmg&kZnn=M+<+61xAYcJQjib@B-&Bl2|Rj;GL~+&;Ml~aAHrT zGQZDks3SeD{e%12q5D0BW_fWH{G}K1DdG>*$+^U+j=<9W0$g=6`htJ3$QU2+z2{|t z9zh--x|;#+qx=}zwG70XWn(LgJH_fdtmUz!68X75W-9nG>3^N$hdwdC?f!46?@`M! z=%a7(o}_$Ucc8m(q!C~XEQ=RxNFTL?^0IX$iyOdtVuI0Rcn#Yqq5T3!~h{O~h48PzNTA_j}@tp~W|(f3YSQ`Of` znHv;Idi=dEu5me9D{EQ2X%Zrbx*U{wwR+U726ZBzIv++57*bg@IUwN`VTSGHvd9ol~op#!*MORkV)BU4Q{8(b~ zM5kp2%I9M><11F!L5{F7o5&l^jZDAP7U`CJ#^V5XI#oATXcWbRR@3hVr znCN(xTDl%yhf1;U(($Ckb%zNk{ma@rQ4vK+5DD32TBt1)~7!u{sv{yn&jspDm^0 z8XeFzR0;5&^=0_XGJ2%$!{7HHOH|3iu6u9VlxUs_P&5^2lg`!cZE_{)Tu{_J#k;@_ zZ?EL`m+i4xRH2n0?(E3Z_7tPmdT`xFax#*Vg&G`qFPN3{d(}%ekl9X@z|yzgGGm72 zt|k4C=RUFZsMqmE>$kKWze|KfewZHV{G{^1ci8kKWLFe=In8D0DziTdI70Aw(y#Xm z5}u0IZUawmk=WC1r~6VOTSrV6Urq^3QdEd$i$V>qm`}!5G}W2^k(HR9AF zH+Pj--ZW)6ro9u0`P;$sAZ7i=tkgIOPn-`xlHmM=>OdutWdq(n_KT%n$LnYPT)SXK z2($G3?3KpXGIU*RtCR4X2fYEG0|Bbm-*t5~%TGrcTrMtdLdqyLCS7eA{l_C0M<>IS zU`Jy!pZ91SNf6b%jQV5rjj@hYi*L$5_rya0xDa&~L+8Jw-e-B%vq4UvbYB%JriaQx#a8z(l~d;_jsI*$u^9=5#eYLN47VNr`c_<#~lKW(cQ zpHEO%UVy9}zS|&2w)NKyf6(10FC0F*SCJa<{;HPPOultksvqQa*-rUA9^-zZy z2+E8vElsoX6VWVQPSLyg?h?c=%m?>D%2g#If$FD29sE;LyHd-O3QK3dIy$aqKhwI@ z*R=5`KRSrUx;AvfWn1SWsX}Gc@0|_-1(qrMay#Y${CPz%7n*pH<5`V&zbgmIzi`(N zi;4W(^&(+DLgp4~oVEZ#u3y65xs%^H4b&{Cm;Df9pjq)*A~E%9mPWKGaB_)qOO zjdA?+CsdkCak`WNW0>KC^xjw@mPs9MW?}4c|DIkS?F?o!I}ewRnwX0{m_~pUW2?6^ z159SJq5kx$dB!#qdYV!X*u#Iz zcd|-8WLdYx8U3Tvy!A7AdNz$Vm65!<=)Kobdgn}=!)Q2rea4%aGgldnX&=?i%3*SM zO3st;vcR7X9R12;uevrq`=UA8dMn`uYXAWL{UkcVaB|a`=kgD~dQ5!20z2lUxd`p# zsXnW_dyt2d9EoD`=e1b~CaHIB|6W9(xt{urJU^!X7(#spoI6^BcC`WE>Xr3lK22ON zt~h^;KYEIcH$N!>{Uaeeq{Lc{--I;(CEnCT#%!C$#uakB0A{6A$(Ku2YXwqb5xZAw zlAu>h^{7l zTO^gq?Ojjj5OPKSaqW%j)Kng}>y<~QGo-V+tl8Oi%L+EwD=iZh{I=}i13E^a$ib5M zd^Rn35mccO8sZA3F`L`7ev+=Fts~@Wmv}w+)u0t~+?*YB z3Cn911ULp z(UZ{AJ>Pe^x&JKk#z z@}#t^tXr#Q!r#`>*P%}_#M$b}dB}S`=YdnEQNK9cO`Pc zz}gT*-QUTS0S2fW&zsNsF(S7We1-!U7PnF&aSKMIrZmk87GiA?9e)$2Yd?Qis zyr&1Z9u$jECRDYGn8R&xTK5MX^V-eVb?%v)sojnC6UsRj)&cBMHHyEA-ylFtyHMo~N(b`Sp3pX&V$dxlz?GvqkZ8 zuBu(8^TIRH{vtnvxN~XWbo*9+AX^8z5TXciZ4ezVG-dm3tVS%tO-fj`>+18O#Ul8I z(&q2`Z*}q_`&4EprEr%vzRSP~Ng71+3N)dQ=HIP7@ZS}TRy_S6Dul-A>NY~iJR+=F z#T~23#PHf=pF9X7uIxsy%jGmhg2fUv3z(x~km{9SoxO*V_ZEm{yaaRWwCakNv9B~T3A@TRVq5NvhtVJna z0OwZ%XTz%Jfg-%?XH}+i{}Lx!!Dqe+i@-Dg2NL_YOxuQ(N=Bssa|$ZB6U_2S4?8r% zyM;w9+%d*tXV+wxZ_$i*7v8(j!L;$-JuNipJ8wgv#hdb5Q5iQZ~^u(@H#e8U7 zFeS#VPAEOKvju1rwPsg)*IIW%$PGpzzM9w^v>zI$vSXxt7iZhKLfPh`pkuzgr<0^s zGqyQ%rX)RLVqf#VfN($Scbvvx(#Iv2m9L5ts|-Ot1-t2SC65-M%(LGF4iUQO+81R5 z*qCy!BlDFCjZdc}QViTl;(_?!5 zTHtr^IJW>c;tP=$&e%wLVVZ+Quz>lI*n(H@;&p0YWIQr5lm-ZYk{f*1A&`ER(+&i< zowF`&|BXaqQueMJAI9(qAf4Hl!yt*n`T{+NjM7M=sZJhlqFA$Bu zvq+}0u$K{<4QhH8oowQGVeKc89hW1z6B5?LcSh4>4?Sie$=Td^ppF+Z8{i{Kxdazz z#C@_|B^WyI7ks|bmOcHtd5c{xilN2g-G`fiKL1`dRha`iEW6&9ahwCmA*>AfCVPs&9bcoqc7v}LsBO9`q==*nkTfNRbpPzaJ+8)PjIakI0w zQ6<`tIFI>b{drP@LvSASZ9CHFn=jKkKqWpCN@RjxapBRdX_Nk1|peY_{uQYKgn zD-+4(slL(ngNwu@4QOukr-O;88CXnC2NyV==gMq=)JT!4fbNh=nP{nO#%<}^RuRl) zebcn}FhBUFKanqMca4=-!cv=gn?VLXRLLYO%Q;IzbvpDyApemu!Sv7vZQ-ufZMQAD z9CNm1QiWQ9HQEc1z5`S;%Iw@fvP6J`=_47#M5|dN;WymIu@DI*9ncz)@NZ<1v9CUq zD4pYXp zLGa@IMOQpGj>9~0Imn_X>n5hV?9ZOpie{CWRlnC}hdWt&g6-RLe`tf1id1% z=;}dnm7vS{diOuMu26#DwjS<@#y*zB1)vHZ2HkD8a5%4<-%KmU`Dy;uJaiCu`a5dl zrHJV(m99&BVDcvEW3C5Sq5Hn=t2&{;fUI&0g8`PH(O^OwQHnSUstyh#H3i+-TxDmX zU)t^~KZI%MV9j^sDJTubeXjk{3U*KHy?;{syVhkfoz0uXNy85y$=ySU^znND%WjYRVzJyEiM~`ygM5d4On*U-(Kb~?u z>M^?zuFQ+^>}QYrm*O~Dgb>5feVVQ5L&t_%Nk)ECjXxVg0`uSzA_WaYL85JCq+lZM0>0_9pyQq ze_)~W$DM!ypTt96a=X^U`|)1YSJM{SG(QN_r0yaN{u~p3AVq?ZN-^Q}ub-e-=oc*( z=B@Zo7kHmDwj>AJCrW8h2W%c@O0(TT+uVPHn{!$=A6zF^H^p&6 zO+T2!CHm2j5dW$WB9%Q!H~az<@`=dp0=!L>x9Bg2aTt91J$^>_MfSb>@0HRIWVb9T zSQQ;wBzjgbx`9Fb2lkkVC`AeEn@;(yVN&pod&P=#)2D~5&%kLK_}Z_3HMu0B){7Wn zRp~eo>BIA}J`rKnE&O{gs}o6%`g(jKCXU9L3?EB>$ey)-2q2R!YPKNd$-E{s;w@*{ zTMO$_b#J9H-mjcIEu1b|i(Qm*`BL~4Rw0q%-MtQn;V<@=aK zH>`-V8H_QGa?bjr!C%1uBIEYCZ=+RjwBxPJoz1UxG=j#4RQ_)GXXlsv`4j<4;hSbLZ(p7o>UVoWg_uF5}TZEXW z)SOsU<2p^p$;1Y1`Jzij1i z=^rdr-H2Kidv@RUh6;bP$@~nE*7@#EZLqn;yu*vT9z0oWZQp>ePMwjeY?@bZ&M62j zXL@tw-2v0F2Qk49F~HaZ-E0(y-jd9w<;zX--@BFkx_8#MxX}n~*w%inkKREnuv?jD z^0#yIMpgQNp8OKv5r5~mjey&W?dU{3DeUy`#I?E?x!SSqGPAdf@&>86G8msJQ2Wex zA*6B(3rYljoIw{zHfO|C6tGhP6i&QV(KwF3aems|l(@QyHmNuGcr+EpCTsak;uI0- zCM8!*c<(Q~9_X7I@JzKj`9nDHh2U)KvlqxtZ1pE2qz@Yf{e2)7A&$8Sb;CpaON7&_ zC!8@g{jqnOG|6wtBCqF4Vm{bP$l+B3g%NY}#~Woc58Zggx&DYPbdt<|8jxiW9198@ zsYuDSF3(?6DF#(6uk#6qg6dUD#VzBtgIX+I>eKL`3dMHPxj^9-~9#jI@qL2Y%I&V-WO{-%62nq zyXoC0>tV(>JoWf068(8+%SiD-!8N~N*{ib=u4lvQqh0bd*-RV6>|0&DEaEr(?llz? zHmQf&RKa4;v!w&F+Q6@_7}u7fmhmtgC1=2DgT?A-00coa5v^e<)aTLdYCp{mF0 zS^}0RHkT;uGM>s)5e1%||J^$@eh&^;OGOsGDCc-xVN*wJNo*-O_ah|1g;62lz99_F zR(uDDt~T23EqyGHxn6XcA>qg|e5Mm{SRKu+1@tk_s7J67enH{aU|2{W6)@ zi^V|ds0kN#3gt(wRagKD+#w2t33S%3(6>_I1;+3}HcZ5%0+#^3uz|ANk3W{L4tIEy z-^MTtwXdHtRbAVV&Uoe0v+U33M5&2WFcmHY$xI?0rlt#o)#%kaU2SH?ZuEyZC;dp5 zp&W{_aaXbaVk$$b1fK}MNoJ{ri+HYCMG2o`ono*P72o3QVU|^tly)xa& zZnlJUXES>@f#yLd^%`iQN)cQR2g1ZQ13AxkO-7E-5AUqr)kru|OzP*&A^b3FqCUAy zpXPdn90ZcqP^(#bSitHP4Bbr%2f{zJEqR6AVHSUwjyk)4Z=%nW!a4IPMw@ZWG!_4r zkckLp)uvmDo!m8#SdL2Y&F-PyHf&zkHubnzXp+}77c zc;#JEcN~AgH+`{h=v5aS4RHcSx#J}ERfe?+Iikm#^Z|Mm+sd&2ST& z=mOCtjf}qi-|F96Wo*|06mZ#@U_tzgsYvbh2iG?Pqs z9#7%!LJ~dp+X}byCW$w+8&k5$Ek3hGUq67q!8xw!g_^W-PP-kv!+@fL`4?4L)AxtH z^0YabCse$WPQEifv0CY7-O6KCv=8WStX}lln;n8hiG?-rd2Ns=yV(^oJ)>ViY^@Jq z(Op@TSmvTX+gF6?(v#-ETFuz{UrQH1Zql;|B$xy1WWsA)LpuK>yFmgu`L(2I;>n!X zev#91-jqgvLKb{5T_KrKhy?RG`BlR7EGN;*Ot?vpGM5V;V{MOHkqnoK%5S;82-1@I zv10%W3#i$!Ttay(J+63U282^bR8v3Uu(7E{LRJ&ZcFfUJ#c3R8aj7vjWaGU zmCtKPm*i!8bn83m!3-lkwblgEBHT%Iu0R{J^@Yfm+ZdNXao3V^{NUkTagA`n_#dB1 z7SNZ0sEC7p407!>Nu+E|R77@xj$@}nQ~7&q4gbKo6Fx7z6H32(6Iyj>vecbmuO0*u z0a07H1k~(T=?J7K+u23mR6RhF?|}2o+wk`zR_P1!wP=+Y!liwLu21bR0oH;kbp%qC zbDTTv2?x@*Ur>ko2XX1m)~LOTJv6elJy}5##b!iLl|;4EcgiJyGK*H3#q*i=TfZ%L zr}0E4C0ROVuDcnkoFa zA=Ifyw5po8Dqi`~GmRJCEMY@DsIeI+wJqao{aLVm4v~!I>u%W4)fH5!f%K#9sk-KC zZFw~0d?3fo1j15H!jJYZ?(RJ6!hc9ukI#d08s(jvWfqo`VnIzAR2m0n_pw{M%ixHNkpy4YZvWoktnYJW!uH|ds)ew5uN2wxzTI-q z0iMz=6GqJnEy*wVvIncg+i8U^EPGFzQ+?e_qZ12rXb%1(+bw3;^|Y+Fh~7rWvp$ks zr(cOx-I^n@sO!VE=a~MQMGVw9Sy9az)Ftk~dt_o3zfqcxU&CvCk0seXJ9^z$r0EQj zp)qoGHFdQnTXH~Q)5f+0jiV!Lw_Zus%`}QS76vP(tlg7A;cDT~XE28>Rf!ERFV z)@L27DFho#a_1MmPH36Z=Fsu>O6gdQ`g;(hC~n>Zp%p6sez~Ogx7X2M*rj7m`K@= z;YQ{bdpX0MFz)2{7_D0*abQhFoZaal^=M^P8oSbkHihssSqJyjQqTe7p#iN7%bS;7 zzUbp@7qSekY1g$c(UDM5vY-K5KGU1E)o2fY1xwX@B(3WO9DQ+HkY4zW{%7<)N&9v# z)^~#@F0^Q~x}XKpL`%qbuKoEVKJM|2S>HEZ^8WL=?zwQ+7{GV-u=T%jTi(8&E^M-< z@Q=fBt;s@v3)L(F^-BlCotviQd%}N1A;2^rC=^Ib@$%lEFIrEXW6OFtClLSMM@OiE zB&P0ZLm~c+qdKPaVzd#8K|02*X(s(Krf)1?udZgIL9aFsw$gVGT!*I;%H=*_BupqF ze48aoiG%#Vo!=$=Eal;WQ8*T$jn#%^q{US^Q?GLDHZ%taE^*1W&i0I5>-`=A`s*Zu ztE^NRp~9m;zS!57>3Gkx-KQi`!#G^4{ylagfZHFHuUlkfuqB~@EfPO)9 z$`O4k%bi~>%&joW`g*37>yr>^*w-*n41{kJw3Mz*9P&_f7Dm&qc@=+knEArB`9@?c zAG@)79G`AOUd&%u*R;g!vgc|vIemKqv^eoyaS27*#kRPNxBdw}I)r8NJ^0I?zUZ-~B#TPfe0Z7b_G=$5&r9r;9287v8 z)yk`fHuP+{hVmacsS9k1aUrT1`V$A}*7QKR^IKWsFX5hElj#(CAs%_VS=?FLO*=D? zz)-QbZ?7r>FZkaN}v?7L9Gr@b&<&me8%C5PdS@tBz_rTh$kcc$q>#*GAx zcS?la=2=s2U`5=h;Y_Jbf@VDp`v->?&;BwDi=FUIOKszgU1?8N`W=QcjMTW<()1J} z(0V!$y;&b^3;QZpL+InLwkiB-lw&0Otb$1IHX2wlsB&(!@Wp#>%jfs7{RA{o>UR*z z%Gyd-`>SM=?D||KRZIqT1!tBlDAwwuWFX7bheOwgRY`i`OpC|#Q4$v}c-JBeZATxU zLXGwPIW|i>(blKsX>=nAwscX}eJd^$OLATQU$$aUX}@4fr+$~Nhk5f0gU^Okf+$_c zrsDN0nyVWl45#>~Y1B=jLN89U#emh5D4+5I|DZsn&9Xu@x~0E_`4=y`OLls0s^(+jev7O6crj;<_pNDw z{1&3p7c}aprGO%kLSg3l=Zu5x=!F&y8{wFnT8HcwCGY)m)RJF<(CTf)q^~Ge9xWL3 zk?iAQwL3W7%ym>j#Zyav^5@Wi%}2kMHR)f#c^CV>a5gA_-1<@2;gw7iH_eBLafs;L zo#;BZ2oo3-lDSK=YaU$?UqH!x#S6+}%6jvpfBSGRNY}Q+-EqZUgbz6eIvz1D)I3>k z4>;;QssVMxdZO$Cjjsg{df#~Tz~iqU2ah$z@2llP?6Q6e zu7kb;E071=^PE?46$Q9I3bIChqkiT1T*oA0^(+nM`dk|;5ZA0bih}HTA5aLoWn9}1 z8+QF+%p%qw=>F7FQQ#3MQNAMKeya@$c(bv?YAexhlVA?W>deCaDMsXv11N}FXAl=A zbs~B|iM}L0!p(DW^l;0QR_t3Up z{B=9UjEwTeSL^IB$36DZuctp92Q^y49XQ~*G1Zj;jP>_I*mv_66KF3+ISRspS$E?L z{^3ecyz?cuVzh3Tz8P{DxjiFrie7HiivU%Nc0=dTT_+H3MqE)bn=l$G-b|# z3%W#9wypl~4VcACk@Ujw$5o<{{NW5A#x?3oeB|WF9H&l8VzfYkrJ&W6nXCJ~IuboZ z`NIkE+6w?EZAB`Yp$u z6%ZQCfm2>)EnP57^s%oINgDjppIqlNB1`!x$ub+yn11CCvTJe8O&V%Z|N5GvqDj2M z!5~gO@OpMKOAx1p(j(0-lRi(7|BfUJEEWWFlYcYoAKd7tN#Nh$cyT@gEAJ1CL3*J< zG1;^tt;)n%=>Fg^3*||)uYUjfy;7yD@rb(w za;7=z5?vsmE4hxJm^_is2{SZplm*AtE?BGfYz?!|!eSma8zJ<*x}sX=$XCnjjEhjxCkz+xS&OH@{Q=&0YJFOj zXv;Fke7s>}w5WC4_?=k?YwuzZ#8z(#ZnoC;wIpbjO3}Dr$!XrjUnW3RF-b@PG@~Fh z%&HJiPIklU{z=1!)uZKk_|P(wpHwS9vCmq1(mQRZ+52PoQ^2h?3}`LQdG z3e^Cdo9$^#?aF3=C23o*oS?^`b!?eWEMIhF_&#UtLza2Ule8MaVz9>D6aA_htbI== z#h}0E$l))E8>#ODlUB-ntSK9@w_C1X!mO3dyR^brv?>@N_Z}Nr4Eow6H}J&PcXCJ2 z4g0QnQ73cd#+iSgP_j68Bb4E-a$sJabwp7J-J8zAho9+GyXE1gGm)~j7 zekn4wyf;@KEcx@Uzv=6yua2r&&pCkwvWR!M)hq4_tOmGd(%ei^)`#j(&2g~LvxtYj z>s!BAH=AdzDk8er9aCy=I?u0XOJ$aZX<&dEA`22dK3HD zrMIMHZjV7^)uYxAXV;V+9U7Z#V^JyW(eVPJ6~uE7(z z;`L4>ux`(I$YJQGiG;0PiPOkLU;Q@`uYNR0U&mo-r9X(>-(}z**})s+)PH1I$ql71 zQ>6jCAA(1In+8j4inX(HgvzYr9PMt-(KW>&a(a0&>A^8gO<3f-`WK7qo!RX=mA2iI)1)qQ0qO1GKNw(2GqBo@SG zZ&z^IVi8|Zx8T~R$~l4)sYBTK_*P&&<|6)JxYrlF9bmjJWO^fE|3NS1uMS{D8R*<= zX1^JPl^%iAqaV+y`Lg|6t~o;-uv{y?#p_^NBXXCXRm~`Z3e25%yx8rE!slfp-O|9{ ze6FG{a|{Tvtq-=@6En0G1UF*qcoVFiuG8aq*)O?O7hbOuMRpM=P}J4b$o1zX@dpRh z?qv9qZIX6NEvajT=3$&>)M%;hMPZ!Bk9uQJ9AL+CGz?@<#bFU)g0=knw1i5aGF)fV zgiBR+TXx^;6k**0V^=$tUMQ=-Q}MF?&PP}3XJfX1bG|ude6#?d8@&lcfjLrt_E6II3pH-na0}Ef|D@r0h(- zNVnhjR{V5&QNFNRw?B&-jh9J8t`VL(=hQu)W$^^^kNopn5wua4N6VG&stFG^De7LI zH{<%tUJ8T3se?41qCGv8+%;q`n1*pFq^PJ~rtDtxkvyqP=S|e1tQ zi1tnRv*fbOGFhF?szM>mi*Yg?x6-@A72;cJaeTX#3P-?-8qJt+F{3z2fR%k}L!QW* zwAt8#HcCYkc*T29NqgMZADE7zF#SMaUA$*Ycf?>H`p}QO%w^|4G7d%2qFs}n4HxED zZO1dl16AA&9evzqYrYkIgH6sKu%D);N_pvv4KBE)(diSs+4|s7aW$S^y(1%kq0pyB zrw`)ffFp&@wZ|Xq!@jtFs^|0!>8(_z$|p(ksP}t{Rr#8k3kVGB*TWp#vb$pKtJz?e z?b*TD6|c()F}ixdcM}5Dhb^MWJkkR*zpC-5E@hynBE{BPVXcjI3HQQcvyMYVv`*S`pHhXVfFRjR!e3sgLijuRAnk0OuyVO{K-HorUvY ziOUlbLTIgKi!>XReqq)w^dh+l-Y2&oHTv}~j=y)43#2n)FD?DY7%KesMytjhDv{wt zU4Yx?mbUZHI4gnupKGJHaiLu@?CMD3%N%mMtnLtV$Q!v2 z@B_Q-MsS)b#66@pjjJwM8l6>-YC)e*W7Lyadb8>Gh-`nOwI_&=w`ip=lr8qs$wzo)8{d2z?g}K6|+y7{8KE*guK8HU=OM%E z);G`&YCrlj;|n)I*-3_{hj-MNE6>>7?T8UAn*rr3(f5_DO{W-HZ;YNwbZR-sl+o z-o5|9KA-2=z1`P!9>@!E?BOYp)zVv;DO;;26>h^)Dp zPY>ZvVHHR}ikK;*Yon3Q3Gv^3hT=4`m{#4-!~+r)33c}P8)uHcU*Lf?B9_8{#mhjd zeeZXkgeEQ+rsQ&pV#iX7SQ802lOHA)_?@f6v$UIBh)AG;QB(MFe?Hm1FZ{_iVnxra z%GbdtHbmM3^F&)gr#R;0rYM`2rRDHTIWE@xdjxqr>Z^hnTq65XL511sXgq}(<1yJ` z&)ERl5d0pa=x8!i#b`Jq;!)(dvbom$NtN}hM-`Ce=FUwTuXCM)O0UyO^q zrf&%uzLp<-e%Pj2evh9^V7y*t^!b&?Vlc%w7#!KFxVg=pk|QhJnFn$iLAGF>)hV+h zuNPJOEb{rqQE4`Bi5o5nsDlVKWQy25pqLkj$ze5X1EQ_uu!fyAG1)SwubslaCdo%< zuYx0%PUue=_wTK>3n25zP~36ovy`>Jdk*3q--_o2(eBB8I%=<^(udeWK~bGFADm`= zONDHS>)FKxc-unW{mOJqQYP>dU;&6mb$5QYVXR;M%5rz*c~1Y6ZTxmiU_jVXy|=s? z_+&$r*q`KM?TmrPtWpw8(5w|uDuU#Uf?|bm5uf&J$*hB4jb9s$#aY44$osl{^s9tt z7f>`jJpXZ(WD;B88z4&{3uf5^=9;gUddDMUAbar3L+ZP(KJkvRJ3!~v1PJ{_67CbL zO>~Fgd>$01|kJXAcDtRjZKBmNz|A;9{veH&kbP zl4LFLyEwH~G_ms19gCfa>#V(>!_iO{nkYe@B7a~HFc=p|ybfw_eyPnhBo3{dfPzuW z9nWs^BtmordKZM#9JwU3(ie7_(_Gd!64i+?S1!fv!&aRS9<9$QWnu7W5!#&+t7p@OW?W7hxr=&vqzN6lL8tIaKaUIU&i<1` z&6txhj%B@%u{J8Ed3_McghJvw{!&T8TylTlOecp8mGXVnZ#_f+3w;Q~lFA&(J!TTNM8@+m5PhBlDX4A}F8?14E2#Y*$CY^J$ChTxyJ{)#?2GQWkk zx%pH;1ysj7QtuDdgxsbB?tC2=;Awbh*SRdYuFS#Zv2SIObSLb}N??(Jh)$B-bL7Nmy2|2uNw6Cu* ze$y9Y3hp!h*qCwkvcuA|`rc>TxuV)|O|@@UR`!ODWCPj$+{I;*eF)R$rqpF_?&SQD z*qRS3%J59qRom+>Oyx=gY#}JQn}6u>aOO4aw4||+TMRs{%CZ*Pt3~l&$Y5?;Yv8`o zz|+K+iucs%_Y1&U#}fT-_6&};05F4T`>3PMmz$t5*ztdl7Merbk5cMI?~bdJ#?M@R zRuI*8v*muj*h~Giw}yG3-KgGaAKtc`)B6l@SLLC=dKbA57sVY$tHh>Gme2!<- z>bZ;e_yFA<$;QfBjTP;-X=JA;RbI&KMy7t$g68)X*0)&!^fE#x{q`;h>Bp-oEEuMb z>7qstMpx67j{Bc1byIpFr-vA+@>>{^@0!=Y4D!~hwYF5*^1KBU`?7@I97UzB^gpHf z_zi(eD)y<_L7BMV20YlFRP%8$mn<<&4a;oI@VR?6=srtMOw*t1AJ1Y#phg7$bdJ$M z1F1D8SdPYodbZDw=wGzHJVqS!@FB?c6&}8hLL^IdJ%aVSC%~b6m;4g~+|+p&%bBSlf?`<@z!r6amw>+-`Bt4B!g= zt^N8NJ~he zOO;(-9!oKQy`6&kd+Nj=y%nLLOmlylta`Yo?ZARulCKc7M0 zSxe5f$&B#L6W)dTg(@~fYb)@qCDI>GhIUPq*p{|~=W&BXUmP>*a=T4f zCZ5K@18vRm?pc0*Xee1pK5v>EO;W>X$r|!?Z{#g6r{4+vwCRvn<-GIx!^+(IR}TvT zE%rlS*XZpOANg3r4Pv>ipW-{e`n8K_M)j!{4pC?!E{$y2n>mk>uh&js6hb2V!RZ@$ zTUWf>YASmIiM2cM9eo;?;sKS-mN$W+|C_fWy^%Arcx{>=IGxrIs%qQzmj zJ~jI2azAl1zl_m0*Fo{Wp$tW-O-+VNA;MY!BPpt>D!=#14oZp5X#q2vvCd#h@v%@T zeSAlWx2d&h`eRFz>B)!~Vi@siN+2IICLE7qffSVABx$zH!tawS)P9{eJf}#Rm?}$C z?UgduUatCy&|gvw@|6;N(Ny+vfDKc(2ZyO1tp9Phbz&TGE*(bdw)=9h%{Ij4IPK-A z*Vp7pEvI&MtYCM|AcDC5O<}EtLRBj4hu2GYP;8$ve^SR1+oq=ulJ>}|2G4qQUkZhS(dTdNtThxQ?ndzIQq~?V&bt23Uz-RrClGT zSr`o|P@O9a9KpD!<2tZ=9XxoIltK!94(Lm??a}cxH(onJ7P<)3I|4ewTtK^D-RM6E z&^-fYEmp%bh>MT>{CgsuE}>k;)BFADsoQIVM^@59!oV+&R?YW;?)i(oYp3VkHx{bX z;Gp8b9OJh4>@D*G%dWtExfe!+T{N8P7G;C0QeqzXbs@K9n$(9ns(ER#$ev}}b+>xx zDt5njIQz@Dx%NkLKbD3U0i_VW3uzx*TF)P4zluN&8M{}IA&?hY)3-+t$Xma1Y<4(b zWZ}}f!qYxQnYPlr|OO+6uK?eOt}a=Ft%EuBr{7<ibbny1 z-m}e@#N<63vJhaYyp&$WwysG-6kt)^Y`yzJtB!#6m{{7oYze) z%}vBezPT^r(Mn(0g4pR8_y(VUOKz~XoAlpmU`Q{7bqqvn}!VGU<2* znF-!3#OzwV8gQ@voBZi>n4!UsR8{#HY{rC6I&V52)dgiDmcS`vgdXU&vN4cqax^c8e z+~WlkvjXY9%`YfUD}Qkpxx#UQ1(mJ@_Uh-jbP4_Hm??^yqwiYkHe}!bN2cgfdG>nD zZDO0u_DF$c3nH++|2vS{B*yeULu%~-TAj>mEU_~QQ7 zx}YwM?gx%qX?7m6$nheln^?6I5Cey8rmh?bywIX%T9@j5&(t6h`>iTzoC=5$hYWYt zW+bsMhGzEN^3)~lRSM~B_k~2T#?EiEOTfnQqqyWL1L!7}K>sdi^RuW4!J`(~$_FI^70 zvpX*5e)ZJCzipbP#F>rBOS^>2H4;TdfzBtm!sqT_$?G@&KdC^U@6{EJfFzNHJgBew zQY?LHD0^@9=cPQVABW)3i!?kf8rml^&)9u#tuS@J0B(hJI|(u6kwT4QneFX2Y}sf` z={eFdL_fg>E??~;1Z@TE;}FG#-mK(^Wd~Lr1TfhfEjMuoeIotn>DBwh20*a7sjUan z?FL&B7^PXxiZ{M>?ez^@Uq@?24LG$ZdBu=&CUXFs$9cE}JVr?tZ(IOd=!TZ5 zyIOBLXL^sDCik-ccRWc+`N5>`eg2+?wz3Pkkj0z&-vZbvR67fvRttTiNarSXAvsGwE8o| zG2lJGMMc@|cs@PYfS7n79dInT@IN}uqH0>%Yu;2yh5EDpc+$=06?=KSw*Sp|h4kWc zsFy%!iN_<$n&hElS>gOrNfg-UrVcECcNd{E-LZbsfPVzT450)4;<`SyPQQ6P%9%ix zKq}2XL_&<9k1J7uRT?frys$7^y=k{oc7XPD>auIq`ZCpsc*5tf^%4{A0OSkw@9u3n zNBvEay-VCRaz$u%;b>J2&s+Xc)JXcp-6^DrESJCRt!w?ECQ{#7(Ud+!IOLevDryqCE7J^d}}DBUjD;5PrE*+3_pQKw4{yG3r!|NsHOBKqpB=JY@)A!}>GE zv@l6;mb?DhJJYs7thZU*RjSGzI3G)GVECrmvt`9D*_7VQTqj5BI?XC#qp*PEE?Zh&=9mva)NnCZGE~0Y!r^+i@B9ub{6~} z$q{Xu_H_K0bu>0sVe1I~>L#b{J<}MetRLJT>qglLoEk?exH1Z2lMU1o0T24 zY#G001^7I2?XH7D%7E7AJy8%^eA!DVh->?3`2|NVp5IE-5O1}fQ74isJ~X+ZcEa0y z?c?Xla=*zqbA$vuf4XM!zI@@82XCTogM+$k;Gn^{&g%mpvN=Qm6!)CiO&DmGQd``7 zFPKCZ2Hs7KhB4EvKN+A*anEoYegG6+%HQ2JJws5)e2+41>kYs5W@RH^n1xKiHo2WX zxK`m*{*BoV*mLAG2L$DPA~bP*9)N3%t7HlXa_Q#S;Ds8h#iC~TEc_k-T9?qTuPATR z&lm{|wnjN;A1>0-(9fOJ3)<4%w-2U-szml-aRM&V-fv+-qx-W%f^BJ^n@-?~zCptE zAtP>Y27IOc>ja7H#HU3L@7q$uD*-)1Dy7Lc@3)Sw6fcglIidG;MzlOQhAMtQ+Pgf ztprLB7Pt<+oorEwE4)YnbKzFekVp_3O0DfzI_4);aQE%~WPa*zt@cCS^5n>PQ}qf! zUa(;gLqf+6oGbRsBU&!K;Vg?n!5GfxC>B0)fvIV8zJB47P4(9bU^;a=VyyQzhhy%Q zx{N+7&nw~wHXC&jgex?jOuOaHeEh0;{4XFRRNTrd=111lHp0Z5sK=%lqPvMC#64FD zzO=~AQk}(T*GcSpe4u{|sz36{Af0BfGZw+nXw)q9*dpHb@b2xOD{a9XCj=n|Du1G! znU#6P;_V^`*K_!|8fjUZgv?Qsb!@q$0s#LPy0dE zuQFAuSU-3Y5G2Cre0Hpgp{5L^*7|It--g04_-A-Ou;p$``X0&2Uq$TJyKKSg%qjp1 zoaJC`2y^J-W-~)w?+X=M+Gm}d>mRDii7dre2q!-N$w1|9c4Il)2RF@}(iGJ-9f1-F zvkCs_pO7g4s~{MP*B{6B0-d6JZ)xl5rz9BC1VqDUNK*4v9qwKJQ!7^pxpoEXT}0re zdv68j6r8JERyc7#e!1~qVe}ko?LVMDlUAYgh)qAL=~dYH+LGBjugLE!)wdMG=g$Zg zdD7JI_5dXL!jIZC)ftvm0)5iJ3Kt$2=|^D&=)RIBaJ3u-mSCu)wKPpn$Ba~zX1y5? z#hBMV1}PZ7gU3qheqF8K>QVGD&$*HA({Nu2Gz6D8S5bWM-^k%eKehu%bbA;0OaOgN zYOF4%Q0SyMB`T1~8;_dpY&(;em&!iXw4)D6Q4flx-_esN>agy?^IjC|L)W?43eM*GHJDcxp=FyC9#Uv^$jk)OjYB& zp?-#tSbnr?T6??H5H5qMYeU4Y9{`B@;HMNnk~Q)oNa>2zxpYExC!rVorTb%!#5I;b z&Z7rPJ?65)+%)6nyRV~}EB36lcE+yNDMnqaiJzf%dyviExnIHUY-i2PDygu@ z{>dsJP};f~rNGX!NLDagnC`D@+m>AM)XrGzRF)naoQfbQ=r9qMQ$_kHylWHv0SKfr z_2wM{$ma}nle@3r7=(ed2M*}XC;)MX-2w54mW0N8%QuUyOs;O;uf#?5`%d27&FiTy ztE_Yieez(R3VJOErl`j40U!9q0b<9{tVCUes$!9WAg^q|+oL7(u(x%Mo`9Ln+-t*b zzP)84h-`>rG@iSCc~RyY$4zW7XqxsVQ>YWrcyNWt-mty%h}G5X&?5VsK&NYp(+wLq zqwZBSFvdZ$3I}}3tf4)cP`^-HXTGbF)C1}JFUVv#ajZZ4i5MaR(4{S+KYhysR>!Tt z{3@N#Go{SkTT7PjgJ29->Rj18ORtWfrqZWp7{u3WQS;?7+MP-#>;>_45i#Y`ceRs@ z$`>i6ps`08-)lQ+LlIA&6&x8Bet6Op(OPa!{JRgCnYMOL*@m!o%(Bd>$D?SiBgeYA z$fdCH|Ak&wO{`52X!$S!`*$2mcZm)!r^)@(R$%=${I|Ws><2Awhh^%Qr00gh>YQs{ z)=<3enZc~meM{Xkmvbq2(c)lD8%P1_BD`b9I4HDvPe#_Q$so*A?Ll5KCA-Op5#Rc$ z^p{;#Q*q##+f8Z1#C#?;H$S1?#7vURZ0>+p?^#O>k|!ZaOBB;lbU}>u-=n^8CiWrc zIYz<2>Lo5M@ngIN9zG)3wJL_U*aw_tu7utPB##8pX7@`m?M6a-g&FF?#JS`$op%W3 z75V8QEd&|7)ti6U`KqM7a=S+IgxATfAawla%~asvgC+7!*f;wI{%i9T%kh!9#ZZ(( za=&qGts@LF2zWwVR1MnzL=q+2rQhVMOjjmFF6uR;ocuL&XKK;mGG1zxVZ9iVTp(g$ zG#!kqfy$Wvj{K@XQhnU%ObYOGJxpn)cr%NCFv^&Eqx^4gzzScf%jGq(fFY_KO&ym# z>JJg0Q~)?M+TbO$Ep$Rv*o~KfqF=cZ2tCva`y?C<4cAtI=WEcoHp(${C)J8{Qb|kl z5=hRkDBB@L%JOE>K?uSBfXR|=?!@!NNlD`&&$^>=0xy~J5CnWgp05};P+Rs$d|R&81r zZ--5?2K}R6n9yyS0ovPyh1drCk0gc;{~~VF;n_wP({6rGE006vxarbgJaE6b@FL<( zv|)V+Ou#abP|o%G2jz#)i`hrS1~~V_uPY>Yx~V`%YYX|1Vv`SNHO)+0sV1Be+h)Ot zy)>)rPq>u9#ojr+NbLwA5e0=fBw0R zah>R{WfIs-@Y&cNDdORmAJ0OeD0sJ~vvJyu(0@tpnz?@Yt(+)Ke0fnye1ojt0G2Uo#I><5Cyx(L+r`uy1eHrQXI6%b-y{!#y%Wy)=v=99f)elxY#f zOel07h|GVu_jIHU9O3Z9HUErUkJ=Z)@d-4Y#YyY^Tyl}ZP zHsI+r*7AqfV$EiaD{!r}lU1^Hw?cB(cb?@BMar4lg^moHKVi4eS0EiH6302iWdZs} zC};f0VdvINwhoac2;}^a(Va8rRXIql7W<-LtJyEm1%}Fi<;rN^?q+6o znF*JTbGJ(~$e~vDM#?Wa>L`}B1-^KpgP#d@*^(aVSD)I;mE?D)U&cJGF|>`hWd-#T z7`@#6XjvU(O=$oDuHFJw4cRLc39!v2f7YO}K(i>0Ty=AoEm%bPbGYwW0w3nnj{jnD zn%~5$n(}_o2*zT-sW56eI&0AJ&@#HW-dTuL`BTjhA~QK@(!}cQdw;#ku3mzf4!O!p z5+ZWdmbAAgeUz6u=Muo1*2fs^R##tVQHWHb^Xqrmg+6i2>vd~#K0EDUsd-V8y{Uqz z%fk<^$%g|uLRdzdV~@^wDbMD_e#CP$yzlxr-4gS%&k$s6P>=GEv@=uq?v~Y3htrWM zt2!vm;X&vN>)j#tm+uWDzgo_CDTc{!txLsR@nX)!CF5qbjB7h&$gMnHN*wk9AJ+?1eb#B1&?d3 zEH9szejzRYNoC>KULUcUt2Z?5)LjPW80TK~@|;qL3lBT5yx@-X=s8F|e()1~=Y+T9 zar@}jxu^L)chzm%S<&60N}W0WM*j+ygYJ|_v!l(_Is0t<`<%OXCg;4R=NHrtgqe{q z>E(3G`z(E^}$y3Tg(*j{O+@uQ)^qU5}#K$(HJmYj65#T!a6-DD_-7dqpzRA^V;CYX#|Pi6Ng`;>=ueN{I zL}ng7Pj3kokQ0!H>Az;vgZ;J*`~>;9ZR9xRQJ-rpD=euiFe<}eia;AO%6SN>OUq>x zo*91ZQNskLIcq>z#=g{qG)ibhyx7C0Q| zTxnzHf99hd_;@Gmr-j0zNz@MaSm+EDLb5cW*#KT&?o|B;C6)up)m-8+5?ei?!K zYYZA})Z1@s0|n8ga_L)K`j*$j%%?2ot~v5hFCU8@1HM5uw7*87xtgHDtJb`o^`Py)|6^netAqCcm#SyNj;Y-It46}ml2Y<(VuNt z4&K>rFv}cfIIcyTY%Hd4C(24j7yRR3Yi{aL1Izyo&D%VF2yr+jZ~5W&X+Y-CitqEu zbrdexvMPtI)@+H4Wo4ryq-_~Vrd3up680(W+LLQyq$z$-z9L1T5w9LTMz zP6*5CIJebg{S2N8wh?DOKi`=D+&(#_#fUp#N9PW91tBSw92npl+;?O;;<*cId^KGS z=ptd>?w0JjVC_``;7a3A`{rlGp#fW;0xh0ueII`$!zDSho#tYq#NN_@m@cey6JF0q z85m`5VGF^O(>YLy=w|MZc@*wwa=ZL8V|f{GdP1rQvemYs-R6*ublrE`b9JZT+?SgD z(0*}BRJtkg;Ek(&7p3wI5eZyxQw%MB{~q-A7smo)ej9*T`2S^^XB1N{f}ZFCGM@UU zSiqM#v1xC(C!43Aw&U413#4O8og>tK(LJ@*)w;+2POT+0FHSI^@yb>^@S`E~h+s$2 zRj5m5n8Ev&nc^(49A}e9o`ppQNm#Iy{4M=5{A(3KnX07lZnjDa)z51Ii#2hCi~`F~ z*==L>Hd!y;Jg#ZCgV#?fV*>`|Qgvlc=yiMLj3XFg=x1j)4$mSQpDk$$f?dslxo0RM{2z`y*$h7ucrNL4aJ+!^96#Q4ea^%foI&`nY<@=Nhj9 z|3{*hTtEGC!}5$vA+bS$gB3*O&Tj6UF%SRBFl@g(xI58oXqKawC?k<8KA!Eg7@|Y0AvhEU2_QQJW+j%T zRwnlKdf9uvIib5{+10x+;X1W(EV<*A+(#ll1O$~Np!H8zRWsmyt5Itr(AJ6{Sf5nSmo5B*O0p@&XaSA;AzSFOWRZ>gA}vT90(we zE{A@q*|nwlt9>vuuKH<*CrPCB@F=nP9TdlvTy#yVmIe3*tS=?daOi%9QnL1$zz@#wFFP{^4o^>=TM{+xVn#~; zaGbQ|ZN;6~^6O~t{@wTn@X~;6>KXf*+f-J#Yg<}o*(QDuJ^DVE+;j6E^1Bi8 z!7CEFk)#V=orqt~;h=;N<7^xBLfM@GS0BReA^|}BBzJKDqA(H@9bQ(hQhC8ziC*Eok9|TSrZ^=Tgg?CV^_2Ge2$8S2W zdB1b1RTWKB4ZrnI)u^BuUGsx6YhZlLx z=BZ1IDRq6eDeJ685EvZ0IspncC4oId5WDm|*Nlvfe7*K8q{$@pfmt+wPFB zU|BpE!aHSqUp9lNt@k|JWaC(}1*8-AIgRb#rf$bqc(b2$?w!#xY8N2N;}dVQ#+-@a z&gH_3=sr}i7Rw1sSJ-FvfnjNcAJgt>3FI$JI5EOoml-?scg62Z&Bq)U!mz4jwzk%^ zD($f@T58|sY;$f8mY(|2-kE`0zv#1Tviixf_sULrWxgGL`u2>+li~{-|M;L6qB@ z4Tk=b3{ll=V~M3Z?+iOZbS zcB!-1XP%|O;k({!o+7qLP@Z3^l{6@pgnFRyPmv~-p$dL*==ZsQ$oFyBlGRJI&j(1E(b8BH&Aq%BP0 z@k4H;cVB-q_E$_-rU_azvGjIjInP{$ZZnV28~vLQz}xKUba3G23g9l*oPT_qCFD=) zA~eKSm^{uFA5ByQ5Ag`{0XV4=}OyB!%( zz%Z9k78qyPfJ1%7%(%LqF6uthrF#2&crI4$-nrNao9zbumHhQ9f?gDGUPKR7z-Z!D zw$PRlzn?IrCRVq(eYKZM40$cAV{ zw@1Q32h@vNp%G^a84^*e`ze1_^4)lhgr(J)SsCN0eiD9Cnv{M{k__ZqW;0FtoS)7i zENVXsk=)3J{hTT>PID`Y->!ZpJ@WbZyhI~5uy6E(V?eQAn4}8>=@;L2?(92GC01`KTytK;g zwJ9u3Pcd_=SmB`khRM%AA!~o_?`z6D$IRqA3Vsu4LkC=5f#5FzE2SOXWVK(<&2m2h z`vS*TgNKHZDRE*V>~>$pTrcD5%l|<-)5ZKii!uu<2isVwn2N^cwO!)wi9=DSR)!LZ&) z*QHOY&#Jo|s(&*Zv+=K!>z`<91KppIA^2ivS38$3ZnL<2HL&9SjE6{r>C;5je9hQ9 zjby*LxRL*koV(@4<&{h2mjCVe*z%RK{DU%8CE179oZ)0#u+aC! z9sb(I5auuufbf;;{0e?wDd56lkKLJG40>H!AGMsnw-c!$_~BPrLEr$pz+j(&vlV;2 zi`9+^j+#KbIsjnl5G82+@m+mPO}TwbI+HPlVQtN7c*wk-t%i+!OO8~zWICW2+-#3~ zMa+j=?6Qc2*RM8SL`~@BXy=_B9GOYLRDktw+|H1tVo~oBjxH6vR*OUbKUt83mkuL@ zqN!s!xN%9*V9mlE^C*O)M}TlSET8WJ*O^x0D??bvpC;AfS|neT-S{6ZO{`uX&E z8#|u1M~)%qBSyU;kf0jq&cQzSyt;KzcPRkqnJvK{XskPpAy zqPqL$t#?7vu(g`m_y0^dapD&LBf(jOS}~ptwZs&DsBsDgJ9^!U2<8Fhj&;ci7L$H9 z05CtQDBDy-g2F;uzVDx5k@#ZIir(NjlVbI|4-dxbaq5zY8g0u={ed#D+C>BL!Eijs zKT5(tX+Wq(YmV8@hRRQQw`Tj2RKgbZi89q=lRfwrHQA@%IlPkSh@C+~L_l`Yx~0DE zT5&q?*U=o(L2xt!cX|1hwtMlqax3o#s*IpGV`78<=2dPHJxzoWt{>VG$E>EpFk3rp zlguC-c+m}|>?B`zaBBtIV;DpG)@kT$nYT?_{3SM`kyHO5TT~q! zfHQR;8tKTT$O4`P4(QLgD)H`0`Col*sEaUY4(IvgnNnFv$MLX>#3)EXwOpm?+E#!z ze4Y)G&W9u>ZGjlx3P`Q0SLsfs!HT(6!Ke>+qGc$PJ4yLE%Wxu^ry4nH_0#>b&ib2E zVXA@Ct^x(#r;p=aZA(t?E$6I+SryEB34J50L)73V^@6xP!Ug z?PM4NRY=a{anCe-KN$6SYGxNJq=eU`T%-E+x_gK0q~Ooa^O=tLqfU-)9u#r?zo}w> zlznVQ_8B^xuSC=WD1ssrDG7zd-P{c7XW+20O&Ii%>gb=FLQ~JUS=HS8(3e1slS6u9 z{8?Ioh@ytY5tpgdq`GKXp?eeg9vCL}5!XkPUxb=VNRF9?9z3gf*Q9B%Rn*{wd@z=0 z@&ob>K~YVex%nP(7d4sBKxCi)N5ZW1fbcR6$#NJ~nW@@X-8d_pH(}h+lB3($WaMO@ z@qAtQcQse3z&y>OR|)uF7msDW z>koS>Y5VZq5BUYPs!kEbV=KNsD)lxGwBkKCqx3eQ?U`)KAn{$1mm+dBj+;ouimJ|= zL} z@qZ*lkWjLRzkec1iNOQlGUcpf>t+FpYxvYG#)Nh3I+OPV6<>J6fL$Jp|5YI2MR$nb zi@Y>woHd+@>)pJ-!?6&Lg!;H78shVL zKIg`vD+eSe7<6RXAmZ(RTIBdyI9u92^`Q%6!}6`P`SknOL3;x%ZK|N_zKEN7fzAKi zAKy$PRe%ac6XC!HZDJq`iwE>g-ed^*^mK4$y8-)H=>Gs6XE|x4qytP0hO0MpH8x;1 z^}0pz=n>7iqb4JtIfUbD=_}xKiLL#?ub1mcFhEYAlbiyR+e>w*|iv04lkIQnNbUN zs+rtdb6OZ4>807R28*z?^kiyu$^Cq4nCzA4V+q(lyjFdajV!=TcVB5`OGoV={+cBVwZ?Nm%M-rbU2H;E;Ha3;|XxCE?AT@KSmwg|T+Fyp*GhN_;UX(v<; zHOO)Iq7Gy8Q%*~Xgu8n3)pbBgTLRy0|xS5QJ|5CJ&O1q zL-Lqp&G!TjWKNx_JY+t)EUb#+7hRE-hkwR7EkO5$gfqP)+uMsry%!cHxIgPZWPWWd zGz|wNg!16UyRQ@z3qc@^kwt=v_9KbUA|f2h6e7zfY*nJ|qVK?rW$1x}gTiCOgL{VI zKtN9m@ov$3~Qap}2 zvcV$~VvRssy*bpHm3#&H>-#fPT2CeI-gTH5QppW=-UN5M;KC7sXJ}78AW#*V`Dd5m zmJjcq6#5a?_GZ4)k79(e`QGG5J=(~RlN_^0!0uHl!YkZr@9Goqdz^JUd(zpxJvsZ! z#^z^u$RtyN*kffbdd??5qy(nh#IGp`cKEvxIox`l815j)9-W}7n`6Y-vd~YLozN$U zd+usC_?ub${B_raWFq4O1M0w;d};Wbo!R(Pje&oR1FIZ6tKmq*E1r01(TnqU z4IIWxiD&E^Q$isdI{+Pjco7kOaaF6mWX<0<1-#>Tx@t(m))L7! zn?)8;J=WZ~%)KET1l2#{1Hx#U`2`*_U|w_ovO%b)S}1H)slK=R6Bo=RzNBFPGti(9 zBAbe`P9ffBvDL|u*^UWjJ%mV&6W1S!$hHvl*4`}65hL9vD@3p)x5ItCbo}BGH?l$!fW345W!5E`qV*h%Ty*~pi!pR zaeh05Xj2LY-HvoV>~!3<^6Bb)lCi5dW4j#cPAs4=7994JdTjbQm~Gu8kDz@azh=X9 zp&`$1fizEZ79fio&fbwsl-Q2PmWbITbW-2G*d@ZQr=}h!us0z8TOMvXwFeFc-Bqmv z&_>7jTfW7`zdNWwiBlQTu5eN8WSE?>$3yNz@Ah9xR~{F9(R(L|ow=)`l)>grMJxZ* z5L?M^X#(xU8sR?=K1&OcmH*T_R3^&Cu{Q$fzYX#eEEmHRhRq=|?rguLF#l1~ra~!= z*{q+}PqkV2BPP5jDQ z>5ymL%Pj@_5GXO7BTD3~Y_I}1Z#E~!6WkwV`Su}47bBi@10ucF#nRH^Ihv}1Sh&hA z#0o4fA}~A&xjh+Cp8~4<*KOxIel}ikpHT6($Jv>Jt?nE)Kvni3{38E?Gb`I&eBCu85%W@PF1Jim9>8aRU&xV6sv z1=qdQzF(b9L`CB~4L|zZdzr~0A|Ah%NL>m_Egxi!(RZQX@}Qf7wKVi>J)KX|fcfy8 zuAC*=i6I0>SN(s>SiT9K;Wct@DAMrWvH6=FK0wKUKX{#~NW$rLTCyV-FKyiF&}N*b zz@I2)DEaOSFpGZ$qRkcBXq!XK|OZ zn)>~oHn$8-uB=sc?_A<5HtUF0NpMJgXB;2e$ChM17Soq{aAeoCqGXx(9i}xrT_hE~ zk*W?JwG)Bq7B?(qnHIjY+zR0^nfiL*m@n@(xB7ACoe9sU*0KI^qvjr8-l%(sq+z0# zN`G|6r$L+N;AcNptY_(D2?%>9{Il^K@DC@pB+7)(4-SK^6jMmf{OKuMea^0}MvbWZ zp|xU@M*KQFnK&vxy!S(6jAy7RIZ>65xBOf9%MP;)x1w-hPhP4-#-c64&`3evuU~O! zK6T{xE!ucxM)mIj=hn<0`x2{{ZK;+6l%a-O3%@&3r}I~=g!^R|3X3i35Yy-^m8~2= zciK?VJ>X;W#W-K7{j(VHabUXnq|hNY!I;%Z{yxTr4oj;|SL|k+@IJz}o%`HJ*|Sz+ zmn{%E>+bc>Wk{k*AG1FfvfGc)7kz_!#nJOibxQE4-`!)w+CX-JKXt`o%$e_CJ= z|Me?r6tUQ|tGY6x!fRkIJR$I~Dq*;x1y<=QYI^+n&7Z)cH%@5+{mBh}pk7EK@TyCL}FeNpQ6OKu|g8 zsII;d|C^B07`bM+kgzcm4CaSXRl2nOhI6yP>E_(%KI%KO228|%zSY*Ccv$*RnjyQl zlFD9uCr>X0K|UVJhi^R$g_ z$BBWA{GiUmI*mc5$*R+N=^;HR&-uV> z9h3yCqKoQWagc+_B@Iokf2&v80?f?C+u~yUXhMB*QME3-pWFGMdM|P5H(?&@t|Op} z49LuOjLg)V1*?OKZ+_c_4}FT!a*=QRGkLPL&>j)HVR3k&e)=$V2T0{ylf%sXzG^GJ zEgBe<{%}xFF0Z74ARWBIgz}36J_el$71-QOv9J4NEDaE)LI&dp_bokQF*SKT1DZ{E z%4pMOhvS2%Jojc404<%KKO{Z=$t6V#{+jlXV5fI4m|@%t5Nme+5*fIn$w57p&D>e6 z6b*$dpAlo%Dwr)=?ae;Sirz9{6U*_vDyuJGg%V`-W>`^4TMA#wuK~|tLIb%bu$Cne zL;*W}ew1WcgJzr+^7MKgKyNf>fNskhjE7s7?x@1Jj}X-(2|%Gu|68+|Uj2H5H@ z7ycsTSoT^fr^VEM5wtOIRAhFE2sWzFCAA3(7|dgymS|{8+83=q`frLKdwHclhwbq9C~R^{UNkLG8osiL@0k~3!8h!`}e1VoRZ`R`a~(fn0z^O(_}%2NTnkC#`7 zhpnTFzeg91m|~zLs5_5&YX4MQf5HsU(?6Hbrpe#+veOAm6z<#A{7zo5SX|vPCuSzj zM!t@!o|h^zl0Tn{$|<%GnNNpTd9an`j4W@Y{f#)SRGAgr8};6X09tai6B_rB8!2^2 zpKU8T6Z1KErCHs8V{xHRUPh1nXx82$b0GuSl%I@14Nuk%@zlVK8POCgp z7)v#vc{B{V@Ss&1QaUk(Ol1JU_b8-Lavd^Z$+VC`<%wqA` zd!;Jw3M01J#+!9Y+%pgoVlk~ZeiqjGRdVdjgn50u)|{6G*#gN@e8%ZkgYOjh6P`6n zz>8-ToPQE!HL6>#M~%+DUhD(lv@3)J`aGAxD%EpUr#W5p#FI=naI0lRn{g(;W0JKf#FA>ippinJ41RF?ux21Fp-D_ zR8l>4G%8J%r{`aw>wVn}HqztgvN!iaQ?PJSu*`)#@zkRqh?fZE1<>ed?^i6nK>$QJ zw+`1F3$WS5K$8>o0%)zX*JgggglMV2BvCI}2^DBs$iHCOF>~;W&!7kk^?pVF1}Jri z1towLB1SXJ&Kq@CxHmh96Yp^4Tjc+7bQW$+{cj&f5s_Aqjwz{*P+&AnMM^|aIwu_i zMo5>6fYKqLfFRPHBgc>i>6VeBYp{`{_I=Lp`2*nE&b9M7_qpHk@(!sjz`@}RUr;a8 z=u^(T)Ikz`(eHO<|EvQv%!F3UVaDKT%(rnz(tSKEeD`Sg<=9SBH6}fDxS!*LaeC|$ z^%Y=W`lJl}o&*BrFBG=wl%%I1U>Af%_l~>6McKq{dW~TjA#O@uWb_`3SEg$IBXh}$yv^`Yu2xE_eq1s#JI_Ji>Z#jn zpLh>ep%3uFX%cN6lJIuNC|>&8_=`K&+M5y%lZKrchES;_>d@@r-@$(uR+zi$LuK<0x{$5^N){Ij4Cz_@@C|Hlx+koU8jcpUJL@ zZ)CPKoI$adX=?3@Uz%!tOgjCMYlCYwT_u{;Hw^@8*wp`+-Rrq9Qb>a70pA)DEHFqw zoEVSoiJ9WGZe2+Dh3?bk+&hmWRHQ*&|0DZ%E=C8m%TFjUdAi?@H4;r#jfFyNy{*@8 zDC&|gwirUvqv%r=d`|j+tN3Sj=YMe8f5fNK=fW6=bRCo*^EX-T+Q33`Ff%`I)qiAg zZiddRyCDt@UJQ)=%MO9C;=W~}f43bgYr#B|w?6tWJ^DbYV7Qe|8UPq(fm$oWl)z0( zq8K$m+;%i{(-7|-a4DBoebMRK=Jr}5b|VtV#5ykilgF-MO<~Lq2fk`1_`%c!`{FGQ z-wT%J>z9>rqL4>i*6S<$Nl6w0uXqG=%eRfaVe4M1?wZzz(5{q9;ssVxIs~6c1YV;h z%T%KMdKZa~()$Z?J;p2?(Q(4Q}5fYAaN==oe za`_R$5?@>&s|wV4(;;gnm_pO`VqsCAh4V{oqwO#*#_R0joG%v;R}!6WLUtHFHaE#!=|ub=h2 z+<71Jg`?+^@3Ak!tbXJuj-hNMb2~swP8RZ_Jy}4*{PL5pkgFfgBJV;n@C}k+A7$ER z;4bv}J-k%vt6O3PMzTmpO4L3XUoC%#Vyd;j-a^a6n9IECp;yFO)o-zVP9Jq)7RX8n zx=^WbtoMh_A}V%|++75VBz155U>;zysmK!!ui;>xA#Klcs|bd>=8)6W6Yu)U$Soo3 zH4S&+#Cx=(qR&6v{aF8j;X0aZB#@c#8ierxaXcf?v|;j6(!ZA-+oQrceed1)6m@gq zCRH!BkIivK1%P;qHb^_&P0oSe*(TR=)NMd+zgtVDl!@$%{HpPfvZ;pUVv zkIwP>_kImUm~^Nt@~7^ubV6ymQPn-Ej&Sk{(CU=pM73k(Vw)t?!Ms>+zl|(uNHG{0 zpkJK?o8X5Bn2rhla;ESSzWtMkwdKK(eP9gO9sRJO+U-S?|- z&Hly?5Vk0|pHUchKO`yr*ueV^i!o z&B@M;jg8$uW?Ywn>@8NY?w)}<)5X3#&SF;nO$@3j)H*n5#~x69KAB}jJa%}} zN1)MkdCqOEF&b#hX!4RW+ZGX9z)QEugCa@Ss-X18t7E#0eYiAV-l4HYB?R+tP5~eG zr^YAJe5vS^FDDmv^oIslG+_uldHIA;p-D8viqJ2%D}jh{*f`=#Nps`cO^AyLqGnU) zECHdXojM>AUsZEZ(h&O^KJ?8?ZrPGFgQhbTBR*1T{i0xreYlV2T2w>)UR*HySA%g$ z;bXJ44m-SEUAb{DvJv{H47B8mTw$Pa$nk1aWvX8@*>k zJBnbZF8qhl@>;yTf`|shx3`NNzN}p)VSCL>fNxQI@weH+K;4txQkeIIWfl5OikTFJ zAE<59nIssz*d!M2+}UIhvn)nsW~^O83^8a$#=X#%T2?MRtM28uiTNf^rD3q(+sAD7 zXBdWWZDY7aWLlQ0&nK#3%R|eJGzsLY_>&sfGLeq02UCpZ7PrZ?ohzE={zDC)J%Yz5qGN{v?hc1uYEqWDFX9baF~g?XfN=-$1;wx;#zyqkENM|zMumAXJkl~2*<+c{ zw6$o&m@29s$dBg*yHN10g6;-)n~1f;!cx;x|@o` z$2lTZ_V=%)Qg<@C$+Dq=B8N|b@C7oW&$1X(U772-cEqJn4zXyU>3!u@qZfOp27>8o zY%6}iGn%KnNjnaP+=$pi#(1^`OW;|4tk6`@m@m%ydg>(}!0pCWh6hMi_piIe9p>-F zO!Gyy5Y$dqr_m3C|7MDg*u^>=C1n%g9d9tmm0Iu0ndX|8QK!l;M?cL4D;Q?8@}<2| zdq|jGdJPN@ms~C52&5LP9)igsP3S9M096#fqkOY!#)_wy{1>(xUgf6kNiU%ez)-hf zW~Sxt7xIf{Yd+V&FE_2*z&dk=ZRr49ewEYe(878WdzEF^FnTHLo}ERx$pH#qgGXh{ zW+?N2P!DzJ-mOz}RRm`e5qIGLRZB6&A;%oe7}ia{);n(7v(eTClc>vy)*qH6d@F(e z(GDkEHs>T63A-nD&M8M{bsz&G;*MLSLWlxt9fK_L{ZtSe0=mpgAnh;RUzHQzr{1r# zjaIL_r=6#hsDL-j8&^cn3k%XfFcpm3H`uh~EKsY|@nqV4L5s<_jk#dfh%Lu<&N!a7 zs`tjZ75XPZ`|=Lw2^`yJ&^=Qk^036}R~A@~Po-uRI4gv3 z*-NbyI~>3%$&mAJhvPr87&HhdkD5Yh-z>C4N>z5y=HDud|30R*nVl}nrj(DWSe_0S zL&Au>(jBs>Uf1+jgoOehNx?nw6NBpek%9;Pd(>m#_uL0hDIur84yBFjKQh~y6@v?| zMTu|rqy^NO>G+kst^p*D$lJ3!dG|?oT~khv;Hgg9)kMN$^Ojo(l*A`Gt17*btIu&+ z$HQOzg|lj4UrG0XeMVk=$Cc(%e)>|0Ik#&Lpbyk7+o*nSHyuzjFi3YZd#sRlSulY; zcwZ9kTzuxLL3!ggLx{;$Cot}R;w23(-1kH{VO3o{?0b;jKUkEW5J{XMOipLo z#y^9#kXnHhwjcN^^l0_d{&`c{Cv()N(0_4D7I8j+BZ1ge;>gm}op;p=&~I*T$>qfD zUJTl8$|EQHoWaW13$3Wy?Ah5WQf$%|P1NgWOC|iCX&h1=(#u+B`hfnTd#_@gt*>%h ztwi8Ub8?@(c^=|@qFe%9^4d4GXNCXXsz`S4Z=#5On!{gQM`8Vi__Cmp0jIJu{Ds7L zg+d~(?<}&GE6_ISpU&h@<~0ATEfeXqejml%Fr13wdL&B5hYX^-a3%H2!GQeX=TuDe z^aAHJnr{=$#UnWeQRJm^S(|>Zo@*p(fHivH$h;csFc&kBe&8m11|?A^7ZY`tVYpV{ zpz+o2bn}f+naU4`7a(J%cNZV!7Al9ynxmq9Dhd=rE|jbSgrm5QRoQvzFn&&OqORTQBP zpyk|hVjQjnCV%&bz4dgXnUXfblm-d}3&@4;r6?ZYjEx&RNSzCoAs+G8-YcH_#Z~fv zZGL29#~jd!6E3`oH)oelQkP&~zZM&1(GS#^z-DaG|B8KMhLw!T*XAhs*f+tTl?vR) zr51h2ttkx%vJq{X{xDHkjk-uywRi5d)PWp8EQ>3ODbP)eHnmXm=6;)4`!nw0)wfpL zd9jlZS2<-0(m{}(6U8R&BB!?|O{Lvaw+3RX_EtQt9nMcHa+U6HhR~LhZiUzq5m?*K zEqEc@3Mz|+uNX{qXO`mMZ zX~B(!D9x)i-59~$nI&j-LAN64#Nq09MHxaQ7r4SqolkmBh+em734f*zgb6ke7#(nLcAYAh2WBA@oh!to;OuwdR@UC9rd1L+qy5){{LwEw&a{>ih z3Bxg$Ou7H&eRJB;bokX^PPJO&w0>>h%IO7*TXvX)`}~a3jDF?Ot#?dnP0J`*ej>Mp zwPc=^t9gK!0}*&1T+Yfc2K;LL(ijV)(O$lv7Zko@^mF%qb1cTd*!Ha+_rJ4GOFS6{ z442FnrXURKA1DPB%hN;}tNI~&R07|{U8vW8Yah>8y6mFy|2Y|hZSy0fFM)7kUdwbm zV;fy#j%lhzb}O2(RBLs@Gs(<%-89%A$?ls^U$RKUfQv_oE!f2sI@I!n7>TgP6 zG__mIHu%d^CBL~$vnQD?Rbv$x{RRQ1L*TGEaUf=6X~I%2{+u6ww|d_EN9yRrX$^_^ zti%_)4b-#afqE6!8zHDD;)iV|qmops>P?Y}Noy+TFI1OGzWUZXkc z8X+hPDs+my?!8$T9)0)B5bCdbNpnc%k;@r^L4wck?paGzeT@Nzx!;9WO@?x+u_hJv zBUU1sZ&{tbfHXin&M{AXc)Jza&HZ!;n_V|8ACsd-gA!KD9E$q9j(I3Hy2e{ zBV%lS!1z^j65;4-d~l7}KJU1zz9~7U+%!8rT`x|Ja2(Uw>LJ9xYI9VPr-r+R9WB6y zwW}AD50K;jr>Y{=HBa3eaqk?v;S2UcOT$$27{`*6AENi2uevOrmX`-;dQ~2bbsK-r zIv(=tJsEl^iTJ|ef7~Hb$|{1g*?YxMVe&6!*+FDV^$+7T0uwXMvi-e-ku#A?rVDbxZ;|> z>l;HcEBmwjWRY1J`2a(CNKeY)eK9dM18(pOJL9JCc^;L3ulY%ZT!(MW&740PaC$9; zrtAhey13fe#{902vt(PCW770(W>iU8(?!VqUXt?TIH8bc%nb;3DSSlLN%i<(IdLWA zuQ&tq4LV0h`NxNLR@8*vL8)njCRBp;rzh0iZZslfW*6pvLakKmHe>q5kM9=j680qK zS%7w4rQg3|+cl0^HT&~=erF!7(6yBIodo`!S8_e_zXmDKre8BEvq>6QVo_i+5VJ#9 zhnemcF_Fi+F>Dxb=>14_j;=ftTEoaq2DG@ln)>{7=iSJlKbE>vMv*-EAK4(JT`hV3 zgS(zpEwWN%1JRIPY`-^V4DOS-8~gTyjYOPN&`_3SCI8{;uN+xT41@X}ng(f^Hjb7? zE`Q6}%_gMLe2E8G)ssvq65CiYrX|CW?u$*PG1_Q)tU@%Y$k?QhSDCH}Z1a#0@*G^2 z*EQL_9^*2pc3t_9Y2Q#x;V8~#dZg61S3P1LO3KkF!kB*K?i%`qlX$@IvZCm&-V|1Q zLg+!*ZfIP-@C6y% z%C?d9$K!%+gWEl;gIi9YnkiZ)!i+H2kClGcmIdC)hs{|y`YiCGnyOgIdp}>h^P%;DWuQIKgV{## z&dN@I@cs&DB%9o??d6o-p;4y&bI{>VCP9BxF_BZ)JW+b7TLy!)!+cW|4Q{Y(aeRXt zD95xs-H;td!igS-2K5szqz?PMGeS9*fAuD4_mi(ozGGU5v(0 zw4Ig;^)0jLnC5D~UAW081YSX};pndP)oF9Ills0NBScnMyRfJ5mokbxB*zIYh?3*- zR2YH_xgRasZL;Na>DqgChD0c{3a`;kS6-x?J=|=A-(rVd$7;mJ7SW zx)Ls92G>@%2Yo|;;~$31x?~Q9%^dtk)<1qJB5-xwW>?4Y4X_C{(twwI`1UsVT10=# zX%mI-j~^}0Ol!r;CpS%$BejOI8&zgEeJfHWVY4?^P8^9rzc389HGcn_dm4@_i?1#C zr2o8}s*i2Rtu@A%0Ve^-r~<^Y3!}N&o+26=MY+j-Wq6)rr0i*O$CLlaJ|v$qcl(B% z7!sohFPFQJbdXZXi{<8hBslN-Euef$Q>>m{!O%r6@y(hk*O+1QaIO+lNSlFSS1Zdg z#WbU1nqw7$Pd4ot(Y$p5w$g_9&5FD2!O>Y#>-XGzXvwpj2Ai(ZlpwxYT89u3CY{gfpZ6zR z-xyUCzFizE7AGGJR`hLsL2O%5)Yh3Qb&(ck*g842h(O)aXL$>zOpxXwE)7{39U7YlihnA4TNxDMmir+(dxMYpC^L~4 z6u@$XiRidOvj}Vm2;oI=#4iW`SJWp-PPf&^78^p6T~=lftJ+rY#D+ppPp^!Lig@K^ z!O-Ox1!AgE;_?CW#fzl8nFL^tVqRisZ)6}odYu=v95SQXW8eu-IT@XeNigo9{2`p~ zH{^Z=-yWvX7HqYK7Y)*;9BPpneC>Iaah`ToL89)!nu;-yIy0pvtYaZfiF)z9xjA$L zccWwd^~Qg$CxKJ77ywQElRU8;h;G`=NJhzjr5MDGsUZYMUfjC77wkI(-l@3m>!WGf z-_KtAoiy*#->>k=QE2B--t&|H$^u#)_-h^CU>Et5U~>zyLnR2z`b7GEGo)IFMa*lqsBgJ z)X}QpUs!F$C8PlNgkY~Tz9(714fjv(nro+_p_2hv>+Qzj10SL)AHXs)RmC+R8>IhX z3oJ>aP#Ujv7Q$LyYuNkr&!EQ!mIX9@Fs6`Yy)J#s9ea}kp3;g7Wg}wF z8+?D@tGLcY-#C>dgCHfD@>M7X%rj*vy6{P&o-$+gqeU1VadI>gf_-j2Gw*8wRhqmr z{zm<>F*nI=o7k&Q{!5lWU^?>B*-=c=1=I$`#{)gcF5mJs(^F|jB%bu%X(zjqNLq*^ zC;b6{hC)59w>V=M{-8xsBhJegDqWquA~`7#v%;@j`G>V!E;ll!y@b6C=`{*GslVj} z{I2LiV1znI4@UQ_$JYSO0W0X^C|a@S8teLwx>=;t@88|qrWbPu@YJhJ1^1jw=m>B# z6YF2sPxG55k4tj1cr2()&R#b$e!9bDeWToupZ?qbhX@oe^_K!n5iGtRYkx{;H#KA~ z%)ZuosuAKg5;k`|Xit;gjcg+`c@x91%PbK*kP>`v%4M(Aw!Ss!jiu20X_mF;iLCdE zi$K1yo(nBzv`!QDboOjH3$6BLn%!w3VU%46F1Ue*1I}UmAJL?n(_t+Qa-Y2KwpNwt zr>Fe3UqCVLA+^JizpnC>m@Rx0+k!iaeYJ8lXTf%0r;~EG#17DlM{aEN^v{mVo)J9T z)1-H+3QfA3%zM5fgM>G|RRyzf-gRpSf6uNKsl`DRGUb%*7{nzQfO9Z(og-IOCx{vO zQF-B3!-dRViH17b=M58N>fA=2Fx%wOli&-B<1ttfPzGWSlGmbfJWoTGdMII2J?84m z$qMru(I3};TBdj*DSn&XuG(l+B!u?uSe#w(m~Cnkq=34{8&h>DnSynx8qJLjZ`LsU zQDLe4+__Q=y@ITX7+N)C~m}yQRnQjm{M_VOJ^Zt?liA^o&W6P zW8FH^PM>_=(rL*KFgkpI)jQ8(y5zj7Kt01dv009w8gh{nza~GAtED8Whf=%-q@fwg zGUMqG=O2L5*?a+I_64aC_$vbZiX44ddEs8;d5uE{Qq1(}mCx%`pH^fCvj;vT!YuLo z%Xu*;joAP3-oJ2^XCtuF2Q_OZv+8@%pD!!@V)br1+Zsk5nuC@H>xwRzH-kY0#Mfgw zs4|Km@oyfO>G1u2+=-@p|2}>=d-a(|y>H*_ZQ1MGj7jN$GVkD$1G${nZ_H3VewGA@ zcBTKBo4ttSe=;ABD`*74S9;4WWF_B~$)Q+_S61)s&1pXyzK)Xa2Hi!olZF>>qC&7B zn$4`+WnTN-CbJmmCI91G@QpVw1%yjJc&L-7U8Mg>6Z@zj4^Zh{ciR0cqGvlz5TDCo zFPft?km-6g$h3V{Pt)i7l|$FVhBP0!f)y(8CsG=Z*Sm~Yu%)KnC?GAcLRT`2fN zqPeQ51-RP-{#hMY%55Q-k?raI!od(kskXhlm%LyX6Wfr@3)y#{KWOybY{+8W9wE-2 zXpJ9hynvy$WI{5f3KnadtWuqL|(UnGr`-+m92_&}=c;`yai)Jsyw*rmK*p@oqX`u+sY#ybhtSY3Ak zsjUVxGEpUZTYGY)or=x0p5zgvaS4R!Wke*T7l+$_{~uYHT=>r$Z|JIu)u_SHi=i3o zy~*YHK0dSN9BSNq^-i+p;KpnO3w;JAgghi)my(BI2~_ zJ93Z%GqfOMlPF+M$5pBs{qYm!jp@|4Q={BEjWZ!_g0)xDx>s>7({F3X_aH39&p0d* zDX3koUE1?|9`dQLdDZr??y~G41)K?-yoj&sKuU=x7^;jw+ngq?x zXpJXs186$4!>Cu2>MJ2Gi(g>3NViG!CXOdgrv~D#?`m9Z*IK{OKZ!h> zCQ*|Us1H|Iao}R#bRGQ&eFF2(l7ih^X$pb`u+%AZ(PI#egSG11_iMkfK;uF z-}{+w@vI)+=1F@`lhb>y)J?6-TbVvXS3Fr$9%Slkzf9Q%Wt=5q7PP;BIK6DAB#rmH zUZARwKx}RKj$aSM;md@&$-X`KM61~NH4zl#d`@gzkn5?=A}8o? z1D|iN?%j@FA~bv)YgHoAY}@@E?p`wtL}2?H`W6gbjb)d(vaEX`r$9O)bD0K&Y1&@a z5QQ$k-IuJsdl4>jQ)?woTidC<^scvLG_dRf;UozDhkukL@M7U4)-94CI9WX3()Sz|^S|I&kl{8Sab-bxfXNy^=_U?b{-BCH%ya_7K#y%LMF zrLBH>9$7n59&E+<=27_OQ#Q!Rvn3dZuLa_N6rEOw2f;ux<75i+ccX1e$6^rfT-x>f z)4_qr=!9vA!1O_l~tSg@G39RChES!%49xSy=*rbDY-(R;9rQ{e`GB6r${>PCp$^+HK3{g zlOMXo{%sgc8Fs<$AVco>sT;0JM8lI%%S1oURpb7wIAjX zJMT{1d951`ZR(8c+w~mBv~ac`{uEo;=$KE)pTyfXF2xj(1Uxo`7V4BlNjff^Sv$6UstjfNT?(9 zvjr1zoDgC*ic&fG!Hci>gq?K0S2w|rykn;DA6ZLsinug)p4wnSXjh;o@V@}_C(G&L zwO~$+nq;eV)Umgq)EUF2CTHlTV(|BhcPOHEaquJ*SPgZnOenZ4i{0qR-vX=~wQ=f3 zozpBkg2NA^BNv+ml_JS`9>dpaXm+f}va1fIV^Odr5JTV_f__XmvS@P$8>A>EoVdPc zZ~pdh=*5AKwJh}jHtO0zR-W%^1k^E(k$BouZRBXdN)RpPZw5=oo10kcyEgRH z0_6z{(7X@~l*JoHi9#GDIi=8g>YYvB2EEpbS8MFv279z=9I=zpPMrQn#)<|7g6mn+ zfZo6>#d5CdE~ZD4LLi@a?3A%GJ!XbO-AI)jA4PigERo<5^phzi`pt7tRIN5WvA*5l z1dGd;Yr&X>IH*h1y@>f-kq{q9)ZZa8=l=fkTr-+9a^N@l{<9j77;#d0`5;ZeHel5Xg z2ZNoBcC&DWK3WQ7rR#*%EOy4t?}fR(_hKYJ*ciwnCol8ik)F(%Y(<2C%#8+5cI4+_ zhH312Yc?^c@rHmqpTNVx9NQ8?K$KHlYw^*XLqqQz8Izg!CU|GrPh7?n9EX$|YtEf} z>^?j`)*^jkk57%c^di`e^N3^mIQLTO+OCJ^g)rRn!T^$HMNjXz<^%@|1TSYm7yJ^mIb zWTX))W9qJyYsNUV~RX;h5b)?bvW2R+)IwX$*1V16;Oeb z&faSJk1QH+ZRd0ZQ{fR^F4{fy;->Rzd5-oPl?2EH!{@KrXBLn+x4G9N-hp#Ah6TPg zM);7fSzwM3LLu?`J&|RB6eT<8huZYBSLrXukRnRz3T#r2L-?}Sa@LSr|`o#jXjDhY&AZI?X89aZK7W>3>18K z2lTILU_|Q*X&;Do={%LNGc~57<-eDal(E6S6S>rBm)UNR*?olH)>K~Ize}__0QWN= z*d^icUGCJ~%?H(@Ym}fK+`dI*i1qLn4(*Okg8q7fKx}k5pCfJIKF#C5;W{3T$BIhG z%}g?av)p1V3WPNUI;r4g?>cu*bZ9jB=n_i(wlds+)~KRD8y+zra}KmHvg)|JoOHnr zFwShh0jrmYj=f1u=%M7xC@c_e%guASS@>QFI;wzJc98}ejQMim92rv5&Z(&;@2LmG zM0x)fU3(^wY+UJY4GCz^sy*#QQ1~wNSd3pjD>dCV;ZAdW(*Iz7?P(4b`KQN!$*@K| z$y+e`X`m2b8I03>^#diZRKRbLV-h=|0V#c;scuOZ-MEy{Cesby0g+wOj7rYSuOK2w z_u&4BFSS72+}zi1)-1plnK*QCKxM+dz<*|KYef#Y&;q8u2evbhyVX<{>wHtzco41ABNK+NE;FxFQ_gBrWBrz zZkyCq6*&p)=Ydc$VI4rtCz;Rt9!r>8pglpU3{S2>M4?&32fc7Ks`xULhv^J|8GmsM z)4ODWgdvZXTYQm(MIxA?qk`U78sNS;!R-;#Fm8^lRJI56Z zU=p`igs!kgiUdlqGz!KcJY57jURK?FBJPdpbX`#(Ps96#ETx~Hc8jr>r~le%3QUaw zzo>X0_|1)8?(lr-Nf$cL10+urYX{;7VyW7r?=OD7TnhtK)nwQ1Z;!DW*PHeL2< zhqC+99~ewa((Fi8VT7zQOgHk~M*^mCh5*!+M3oAp7O5sL{)9$QR+c|wBOkm0Vh`?WWl{)PZh5*rZQ@k6^rWA=b`;?Gb(xa09qn(u zCHTk9WPL}2)OR5zim$y)3-wRsWY28=C^o%O!2e3vx{4C5;_1Y!y=Z~l2i2bL+OCLw zIEf0X5DA}+Yg{$^T2Fu0+hAK&jQQt>kNn)jP_rphE$B?@0D87I@Grw_xN8s-uIPto zt^r7l{wACYNCc}3^s7m5Ev2?W+`8YUeEsqF^Jt8Fkx4HH-}=zJ@2dUy<@wt-A1_&> zzgH;`Hd+QJfpM{=q@l<;H5yvVrO>0|lr*~;L1|XCN5Px>X}eKc4jwPJ{w2L>9N%4i zH^!c+9Ip;dww>E%aDRCFdDY&Tn;~b(%kAxcZR#S1A7W1j|CFYuWBGq1YClZ<^~OM% z6VfuSvYH+iW5}Not(!N#^oa{lLVt{$bL4pPzWR?$Sof8Y?Xw}uGGUxtDIDzQ&h#-> zN=Kkdr1sOePwHB65kI5egIN$S<%-YQmRP-#W0E?nwrwfa@Z2Rh|~&>KZ{iwGG} zRrjY!AaZlz;?bTDJ=BBK+}j#Q8}^O@jR)-q%nTMz@P6&N`k(K!Ycj|a9i$CTs$NuL zYO_S?S28X}y48j1d1d)xHQ2S?+lua^9P<;|%6@&W>~}51B`(A5_20O%#;b4X%$u47 zmCKr}MM*DE2cII#Pxdz>epB9_i#f93<>`bXfv%HQVlFnrV$OJ;4*Y^v~I`8f~?w=csbXvy9?*!GI zlr?i!uM&<6j~oOe7gR81%|G{NK|??3dRq{pdlyc{2YlR4stf^M2zz!h#yY8FGq;Bc zdnr1Er{nG&vEiX~&0W0D;F8U95=mp_Q9oL10CXx(7RLvTKZC41p^1)sclzDlPWrgG z$}%HxCWuRb)O*I!%UVa6!zI|YB!pk%3nl6YhD=ClUz|J;Jb~t!Tery-MBHzls0h?T zz$qFoyyhb-)#97uo7rqOZh+d8RL2#-H&X0el;2GLYEbszcy8ygdV!L*@Yl5-Vbvmh zK9NE*paM!{(Bq27a~C;3u9tV}^w5)Sa2*;1O6M$YH)%S#&(8d-mJiC9?WT2?@|$CT zS%Ck^jEbbRc$IAVEEq<(SVm|iK5!{Fv8wj7jP(%{A`3>sI;T0hn@(9y{MWMzwxlZ1 zoDO>Y_3{z7e1gQ)OQxD!GLfY)%mRFT7Bkab>GZnN@1^-yTURyZ*q)DOmqpmc8*rAL zV)GD(z947bSXN!>?=v8Ana!L2u@66bcGSxuz63IHr83TKi$CA3f3%ePg?yZ^cxwGa zissUH80k(!nJb5V!^ggBkslALWcQvf7ZTNAgcs=h)57n6UY}Z+*8V6h{DnE6EB+d; zd8#a^)oj|!tG*#gxqd8Lhd)xI{S^&8Yq_uN)~lS_$;CH>(+(U|FD+#EyZEPdA!k=F z(tb#KKA5JRMTutw8Dy zKFM50zBg?ps-pC{Fm~ZKjx_yl(+OFks*3as&o&(EQkDH(}Pa;yl{J zT-$c@;k42#6Wf-_vH{ONiL)=tKeGuVp?V(@_j*)n#zht`%$g={vb-=g5aj*WGayI) zDybcp?HhaU0@ZGAZ9>)3AO8K1Y+EO2ayCBZHL zN?0@iM(_m|{3Cf?PakKoC5H(sA>?3EP>*Gqj}f2yx3I^^Lr6}3G3)38(1 zE5}GImDX3IT#tA4)Ga`VgQG~KWxmG3#Hf1ERq8CZF;+~6ULiGM-s#!% z->ap3ica0B%O%5iHk&?knRo>FTIJf%(-_Q_v9V~~&y>BQAxhv#nJ%_m ze{Z7t1CDS!35XH1*@~a0MY~=te4b9&$--;HB9uf3y4x0l__~jUW;T7ahH?B$(Hr~{ zD?IYCA<9j6c+0tFCJYL(uuvh`|L8oarJcy4^IE(fc>n6>(Y#NOp>!68 zmGj-kCFv-X{jYUQ6Iobz{C4sXg8e{v`JPe+obv+C=+wWAiPDHPUrJGT;rrf*Id<+V4@KN1a7>)TTZ!9@tcYz}jmiL_+`#%;8Zg9$0cm9oL6 zcoWPlFgOr7HKo8nqOx3xf`%{NK%k_{G}m@mYQkej?mKd;|FOu(RD+qEURh%^%PRW0 zk0U#NSDbg(#_FP<%{^hK4o*H8#+g4L3K6!a%o#kkIl7L2O>jJ%OqFrAWW9R3!R4L_ z-ib1|%p*b^g{4F69r^T9f)=+wLZ1xky96zLm2U5scP}zi@E$XoFTBD#zRG_yzR&2( zwq*hA7bxh7TiKUVM20fQR3_!1Qm4nv5wBtbXYwp?wdA$*vNGlJE3B7yp-VlxJq2?n zK&D77{Y|+2t(0;E|FhaXA-iX1RXtO!Ad*x_+jHA#^!>%{x?tWElE#`%ooVtS|F6Wr z9^LrYuibokk~g%OIb1kBq+)OG_e8OFHAJtq`gn6PM$2$E+-wbQwQ2p5YGU6uuVfy4 zzMv?_c{h#y$As`LvZ3`&;MQg)f-bb+=fRD5A?$ogluK^UvPQ*v%fxX=wPH(0;$2?J z0k__pubH1xHkQ`_4&19EU&K;o1eTk1MPMUVWi8jk2@@1n8gDwQi2=!cTrbAc%k-X9 z7#I~!!>8?el zR`{UxD`Ij$x%ncbu7W&0;5(i=%z_ro&iVY>A2MrZLO`JAG$i1nM1M-4D!hj?{0ePd z)Jx8lVc2@fautcvTG6I+1aLAyE`{nwJn{Dv!B9&}VQnurn9x8%)@KV!S`SZ)b=}C% ziZeO=T`I`zQHPLPRv?zIYv=ZZUMQeXMSn*p|Jx zM(fq_&34#Iu}i3jVFs>(uV~*wYSNjUU+9eBc167$%6X~SFU%~zb*l-%xo!s|kH0@6 z+Cp5;U419B<;~8v2W_SXyJx6fI5V=o)hU9nD|)Z5302jn*u+ZR!~Q)vy4hrE6rOA^ zA^5zvIk*vL_LGz#P%2S9_r;a%lx<~a2lmu&+8%~wnDGHzs7xp(>oSLP+pfLzfRg;L zcNd)Ej#4<2>DBLtU=;M4B6fcOSc`~5-?Zh04()LfyEL}J_3XRiW^Au#XrI)$#)I9H z*#LM|bqKCLhct}7Hu~ONSsOJe?Bb^#vw&Bp!%TpD_?WapS;+mYa%@_4{QyYab|vsvwPkZ_Wc3d0n$-Q z3{Fb-i2A_h2Z~PzMF7|z?NFXm-DyKlb%6%dH)RC1*uX(E*wUZktv2%#47u3RV%P(v z2bKvuMwhA+N)LU5fV6gXZew#ycGK8~mv92=#R~o1r3!ZD<7%Qzpzl?3Ak)$r7H}`o zY?D~3{K|JBV57ZS^VbW0GseGDRD`KtK7*-JhFaJXSWlD)A)kV80%gBS+?%>iEM=wn z&80hX`N(`z9XCpxC7#59cH@_Y>mI zW}5zbs#{Yhp5jj=w)|EMSD`|zxH|?FN20d9u({O7r-q`rx9S(}A?S%woh)gS3yt|0 zb5rx6SoVs$vrh-vy_SVPcxF;5qzyAfmKZYM>K-oHDr?R=b(I^9cC1+rp$+a~U1V*w z2QmB3YEIX7H{sLL(_8LO>8JO;{ne0!NKG`d^s!kY81u-~MyOmRpjfS@LC%v9bGsFj zcd-i1GB2!VEcrS=nCR z=ynOOJg-eQM*#}!89`v*YvyEcf)6WC2F{2bDJ7Z8*2Xaijl+f!LR5s;m}CA%WO*9^ zF|c+lpFKeU1>mrcP)a2c?K1ORR)FWGELb^JCAR;bxZVXOU*{Oi!VcR)}Q4Wz~tyszO<{u%-U%*Yp~Y@j&sbI)#UX=4Dt< z$?zAGyx~u~|NEuBkC81CPCFOjW^qV+@JW=uOa1>SI?K4G-!_V)sGyXnbg7im-7pm? z5m1nhDGg(cX21Xe2}uC~rIC&?YK(3eAtBuz5`&Ex69)fh&+EPWeLlPI`#RS---E}3 zdP`Ze-Y>DJ{S3zH(9LFCGhWChNW=N9uDiy)1MDUcE+X)J(?jsAj&!w_sn!b13--Y7 zQE9wS4E7v7L6GeAHS5bNU$%fo2ioH|I(CKQmNQB%otYkLk^5Er(?}TZRHnTnUk0q6 z2_y1igYmSJXLNUA?@TMa65)%Tm6p)JNz;MHHD3#lnX6Uak&(yd$STJfUS+n)?Pn_z zI?JHWq)o&abfbHJ%~IA7{Mu>XxppzjOiJrM18tb&LhR~#qn%)_ZNhKBJgQqZo9Qa= zNNV9LZ^VCO8uc~EWWVisNBD*@d$9LpLRSsIasO^IdfuwkmuJQ-BEMjFW=8+b9LXV# z(&G8P5nJst^DAg!nX3i2f;r!asXrm|CI7?G03!30!_BPCGFKG&g zG+fTVyky)qI$jtM9Q@{Y>jWrGWF!RS|7|C4xq&0M%INXjQ%LK54pRtHtrN!rFk;Whb?yP)%x_YnW}q z^8xv{X(M!SpLUku)jTSkC|(sO`{hhn1`niyBf^Nv)NgFGgwqEZ&A*a|FD^sA_r3&( zsF8~Dl8!Jy4x*_$&$Xvat%sG}tGv-49vwcL#u^CI9D;q8=hh}PQdcnI@KfW6-)Uv# zYlq*YwL>Fm9uVC?cY)P6))t^K+Stmko_1iHwS`ud=i6RH!s+wV&j(zUu|GvE~{j^4iNUJE2q9Vw%tK*uD#=$>yNQU!`PXscWG;OY0=9-Hj4tx{gl_yZ@%S-QY2cg zkWSc3Ak6CO*EOHhH4C==OAz~BIv(EmhpW3jQR9)LtWu5q4Si{gq~9;dj}iRzp`N}0 z9Bvi)c^Ag(bhFv}>xLV_t}yFyX}Jx1w_@Y3-y3i3-1sby_77YklE9{_laTFzQ6{K^ zKC0=%2``h_&zog&Wt6Vs{i~;lNVrIlEQpJRsly)_dVPbC1I$rxnt_vUXZ?|5s*Hf( zvuK{!Rqa{zS$?GtK#H@RI3TNeM|lxUoFGAZ$}twJBubxsH_AnS^jY#N_OW>eWs8(1 zkxuM-NQ{pQS!@8FgG9=x_jkj}rLO+W(a9oR!R*NncKOF*pwx_?=6izpTNUl1u5@oU zR5*SoTuQ=pE!!oA^Y5tS4y(|uB~1S!C?lM%Zxen}pP%2wD>7F;FwabjO@8=z{>2Ct zr`(Z7x8RR$!VMhjveqZd@m&#yOhJ{oq7e$5jnWlp4w=}u<>lsc7@^$hgCgfp3)K2Q z3j7LTeU*(|^6b8-M+D|WgL|LKvSyVXWvI2qsHn~AtJtyqwDhBnSA(HAYSyx)?JTg` z4uV$Im#o*r#w$qU-nmmbZ#FQO*0|R~oP*gEzs{ds{JRa<7YE+2c7_~t;WlQAP0?&Q z7SN=9eD-9J5)^>8Vrjx6VxM4R24R5UwUsK3f&x#6fI5~J;hlr-xX` zDmp4}dZt4Mm)tiEn4J)f5Pqr&0~9H>d3R~?1oI@1?B3^jhNi3H2Lm zz@C@R=U9`4#jkZM^gQlA?NRjq;-}NfIqgg`ZcMS?NQ^%5OY+ZhpCufv=3qG1MMI3^ zL?gGqnD^gkt!pyOp2mhX`f}gAL#tqfJjXO|+*bJRv!N5eVD#Z38t>Nq?6T8f(lcIg z4qzubC)nZef&`1eDU7~r`g68z8?R{EQi4%;YP5_Wro6hQHMvj8BO|5^%3u)U)mxel4J!FtjNz^@J;~{9rysd~ zJSHuu)izwBQLH8vLAP|3z7Zh9#N`zmhJHJpioDc-A}r~L;d>JMq|I;RVKMkb#^2So z0JmIM5kwMBMc0)pW2pZuEw6~pNhBh*Sol%*8aL+K@^KUg8Q4fof_Mc~?~-p_^ef}X zWpj`*>R4l2ip3OeMdp($f7>H>OG9pN%be~}9{4t?q9GFrOt_Z7F?DI1$Ba^$Y3G_P zYT2gOnAPMj)@1va;9lcbjI*0$8gb1pe#BwSO>&b-FLvB3XRcAh^5Jy2+D<EPl4_KFH0L%^&hM6tFNu3D=0G!Bi_ElYCw>nMi98w;;2nA)5anPnIHh7x{mHs0#m^gG86+>J>0;YgYjfz& zCLl6t9P!DX4gW^BDthA;K1Gm`wwl=Bxtvv>yvvt+o`NG|yFTqgaSe=1eD-PtjZXM|>VH&s3(ud3u@|61I47&4nKQ ze@MgvI;3hLp=NpwXv3!|H|pYrFd^B`(mpcEtw3(nQ&;U;8Ltizf+qhUo9dPf2Qa&q zq=h>Z>Fz9d%;#1j$$p#)nY@5N&U#vX?ImUYmpH3x#O)JO@m!*Z>a)fC@p_|M=_>(N z0t0_0MZ_)CqaKjDd3@5W?GA3!=%t?9Cr{P@mv86fZSq!t4Hf!_a#%Il>JcCQz?53eZ1RGG)dq`I@?VbP3 zYcDhQnyH`L(~RJACYtT%o3xYa!kELZ3JI-k>LTMXGh+(y#W|}6?9bK>+{D_Jt zfnA`5>qyv?@o`pRR*;cNs$^(B{JplK{_$O&B-KfJ<0PsVraucB8~}cv?-q4xL>Ifa z+65#h$LTFA3x6OIU5%^lIh^V5wf{&nwhQK|d0Xrz|35AtTaGhbI&UNM#Gah+Z$L9 zP*{sz#c(*QRSUr>a@akzd56SU42Q*Y22)ZM?f#iR$;kZR4y2^~_gYR)2c1Yt2BMz3 z{vO;H5Au+EM3y}8bo6p4fj?J~sZd1=4BKS0Z5-u6y+J_uGwy7u+goY5=DhJfIC`ok zm0@Tc`e=;F1_58(6W0Mjwz#Q<>4D0`WOIwRRUxC~sU_apDcLK6?gA-WA5Nu{Ke>xH zp2(C-!WxxZ_h0k5!p~=g0luyk<;RiSr6rZ%f_8fW?zhh_;rp2PHQ?aWf%>x8GJbzA zCw%g@SucMPkyw0EFffTKUNrB9{A^htblbbz$)F^O5t+s(hO>um2wzOYe0(P)DH5#> zcj!LT=-jHuu2mNKx`x{*2Mc6SR|_9>8fj+~hWXww2&Gul(S-Mos@P2y^Qv-+9|*_< zn7&V+XG(gz>K7I=GhHHl+I20Hm>(H`@A$UJXYkWSEh%5F=K39nHG_lX>(D^+wAC|veODU>>8H#e{Y1ahdH1qfw?%gMK#ySgAissA+(14p{Cd=77ub% zf7PdDin#)&dbv`Cu(2}1OG z-|MV`c+x=`xLu9@4c!QJzDfz-{%kWTwL*)Wif;&qea(@$6LVRi)p00~v8pp2^d^y` zvneJH0kvz@(@0BzX&eS(w|EGflv~WrtiSOe+5R+Vt~VwKC^FjZHmBv_R-an4*we_^ zo!7bBOrE!1PGiusLhk~X76b}*ugo2A#}95XRA=*guJGK5J~&&ctweGlh&*FUK&RD3 z3pLkv+zICmHs#32=fm$d8VB3sSyZ0raF$l+*!W&H*oD1KaF%(55$U<_2I5znBJx*4 z^D){^uz6%lq)SajC|gxQX4pCDiN`9{2`b+g+f@*WcSRsUxaShJLVogtM@m60#-5&q z`>9Od<`(96$IR3O{1Qh#OKFES+?3l7OBYe5tOGC-Lbv-!Tn3Bun5&Qf(}K8l4}IfI+CYuhyC5;Zw=(`BY5BX; zzDzO)6GPs}ymv3wJV{z=g4wnMDtbiO2E+PY*0{bRcl5sE69Y7Pk(xM%lH~pa=NYp% z`(h@R&b)xhYH>{GV5t%v$%_=kv5U3%C;QdA)Ji?XCgkPuHrYv}6~%N$?xIr=Th;gz zWNkxRRuy+ZPD%)%r{_9l!b+vlhNDLzuq_M1km=x;y6S4Vn52AF{z^B9gZ1Rnnz^95 zR@)x+`~F?uf&0n~2{2==fHep~^HeboaQS9rY5Kv4WmoBxpsY{MkE@U(E}8P+W1 z>HO!b#dx>Rz8Bu**)-!toKL10`+8O^7Du;~do%?SQVM(@hLw~a!OPanrU}#ni6HMY3kj^F!xauPk&43)Jx#P>H?X9M$XL)2pdM@ z;6r4>kA>M$e0}6M+VjiCoqEvU(a$SbJyOevZ1?e=QMxXC{c>nX@{tEG0mb>LlNOGm z%+IDAIIG;hrXt7Db+zAZ6C!Z#Th!*fpWrr-O0_6oDsj_P`PnCrU?QZD6prC(FJ&sd z$c|t-m(y94wITg;6e@;UGha@KG=&_FuwCZv6jz&D|{S5Zn^O?ZR}ffP`?9ZdjyLd=^Yx|zL9Dwz|vcXzo({Oh+V z;KsEF6zP8fSZ!qyz@wKCP`O1-Ep}{Kknx>|Kds`8QH0qUWMKwxFoP7GGp(b$OVG2J zk=C4M(}oJ2;+H}`lil!GbV$z82bD|(uQmei1<}Af#t(>+MP@5dt7+NBR*)W@IzOt( z#gfhM@Kf92khLwHfkjF8Pz82g34>rRo_ZS9!96gvqAFG-f=O`<(v z0b%AGB!CL*G-9h2GVaNU(y-oZm7IIYzYA>S!s_MB%4%PQT{Fr?O066W6gAAx$ojY` zLEKg|Q?hW#T*Gm1q!S)tD`j+IC zE^DUxF~0TIRRTWgKh4|Tz0Y>nS9M1CE0c0!9E1XzitC` zGJcOH4N=`R$oAPU_ZMD;M~`Sz4{$#W$tE+{H@%jaCVu(_1-!#%C46~ud??HlQk?eQ za^x@^*5&5rIYM?}T(7rE5oT#SaVR3Z)f67I1RH1JwPU~i!sF3~Tp!tHNRp10Oj<5! z*rk!LnAhTd3Q(%HH{yQG$S;4iYdBmOwFTg&Al~OUpSG`pJcQQFX#C;HR2nLN6;~?G z&GjrL^x0ABh_ayPdIIr*EGZ#WqYk%Q&$&Zj1jUJnSFJ#kjZjm(U+WWhZgnB#FZ0|e z*`u%S6Nbw8BSYu=Z{zdb-Krc*JyRk~^>A;8MpIZr5B$Fs7wE~syJy+072(w=m@z$j)xAAeK!o*pbVREZ91%Wx{h`MG_@( z`DmsILejD}fQImtsg>l6y^lOBc^Aq}lf)GK%CiGuM##E+2Qo8`g&-ZhvJ{8D@tC=$ z2sb3Hyb2XFy8rp(&6vJ`>_#}`9$~11lk?93QFK+0eeVIt43pA(9__kb7d=1HMb;?5 z(q{iLF9CL+Y(V8B`nwi_AdvFc^M;Evl)s)l8cuVtR(zoAA8RO@z*SdS zx&fwX5p=gHFjIQD4=F9mSMjmPh=t7|;&o>o@4I%(6WO=tXJ`Gie|t7vA4 z6jwT-9tfblx5-DI+)h)$OmMyNfWF$d9NV50&U5+{!#l51rmP3^G@s69sF?u2iW*mn z4`c3ih3a2J?(F?pajJ=0R^n(_Oo)H+7z^5bhC3rU?%kaHv+Ejyibax?MwEl!q5fnOQ;{RHhwIlZ!ZD`|3Vfh)?716NI6PE%o>&2#A%i_ zq}n<4{bq0RGMMIg=a<&WeMJWDBEfCH)Bng$3+8V~$PR}L$RS#~ri-JB%DU}ghflNK z7`Xia#Cn4jmJBd6F{97yl<0Oocyqi0>;JQFYDm>7BXjWR=FCQ_6c@b34~v^Jd2%2Y zSoRI`Bz~mJ&C7f^Y&ls-pMS6A_}Wfni;KgV%jHro$?m6{pcdPB|3r{zsh54%oA}!bZQiid%tmNAzSdg2=mE~3cee>$A&5+n;$>8%6kFg! zXM&n#qJ`QaOnRN8tyU?87R6_+aBxP`y0fD<%+j5 zo&-z%tr+U5z2hXpOD-Dg4e`G~Z3JW3u%OqtnMg1=<1H3n&J_odmUJ)ax;O9atH7Nh zIQQ@t8U%XRCdBT%PA`Hosf=jecB@l&Em_#@2ltRe;AHT6u6W@EA)u)TQ-m{AD{7Dm~-e zrFtm^N_?(pkJHU2>pv#cH}WI}$0!8~{+8C!+~a(jw5JxV;2?Bx)KGn>SIXb&A76dT z>5^j)Mcw!SI?^Z3x6zm|TdB!>pg8dzoG0!pc1qE}Rm&gqf&J;;h3neY$>o73#_}*r zlxV9LF<`&I6}nE-_=5UQ3ZEw0I+*nY!?~M-cf`re{)Ayby6-v(WIUUpf(@}6h1X*j z&ngGO#Z7O)4_#dpC*S^ zlZTqefWohT*}&nj91mqDxfAuCMstHR)wP6PU_@}uOfTJC=k&nyZU8Op?VoE-Xu_pE zX%BKvBavRN^gKD9qAx=gj5nskZZDTsnwxdB+0IN9w%qH1jT|rpnwg-dP7G<8VT%0UN%~ASr`Eg^-8VAF8HtSJzW1mq{GUtBDw~o14+dwvY}q4 zGghg6pWN!Qn~&w+%QaLgCtqj1@4z+3RT$1Tg0nh&#CCNAFjrx@nln;0oII3*MI^+ zB*%s&N!FE&OX^GT!{A8g+;R0sY7|5FvI8wHW*T9XSb>GVF(q28fxmXBD>MXJ%M&E} z&~(~aS{&@Qc8w&4g=C<9aHlenSB&6|Tj)fk88vY>u8&fgYdCn| zo98gA&04N0rs_v$K>3$LQ5O$x`{vwf|CkUB~e6)YH;sJsI_WFOwwG<|tX zMB9c1@f*mr0wX7MuCvAD+)rSD$V11(9;{MOPoNH+`Rl}a^{;wlm zFBgLGI{Eb|fE}aS;vbQb4`d-Z`c0X3^;E<({pTaJe3vc??SV|>H_YBqOlknJL%AWt|M(XIgAgq70 zSy0oT#$YeOg?rq?5jL*7k2Z=nud$d!Gi_mmqI`MhR79iI+;f>k3_Vd|g7|Fu`ss|< z0@$NVo-bbRdP2G`w*2#pq^ER`vHqUsz$)*!1T-M_S^^6sVV&s-R3C8Cc@1ME{X7xA zs;S}!-=+ox{OD$|m%r`4+!#EUfv?2obVF_vlDhy8m3ZCPF-#_!%QHjGAkdP)2S~C&_gYhe8WR(Q>EeF$?wSJ8H3FPTUmvM;-d;O!vjf zEduN0!#FKZP;s7Ibah6HVM1Ly=}e+SC7Zs@}S!}=2 zQ(N(bAK_%Nv9zFc(nBK*YQ2JYA;_*ZbI9s9Op)?weW-JpBk0-=Srkd}jUZP@da3fO zCBLs7MOvj(!TfL%Cojgg#~~`bPE9VM>(lmeb^jQQ>?tMB?|O&@Sl0xJ5|ZB&5=olC zU#wAHAWxdFJ^^8nswLSNum4nwxId0}P#%4UT|u|s-Amt2ShuuZW*eqeB!RIXJ9htw zDZW)s>yr&73ev4PbdP=xX1V6k07>QK*t-Z!L12;Vm!66bj$-X@zh!N-4fFgwWL4-uip10QvXJ&F{=21u! zT0!f=Mm**L=H*=@9^7%GfY0SYlGQk-2&n~`sgF|!+mIEOLZ8_^e>!VH`A^b|NJ%_u z19KD+qzHv*SI;Op6$52rSR&@eoa$>BxbvCwUR*VP)N6$uRbKyIq4Ca;iPXnE9ik57 zdo=ktmQTTr2{92(oT{3NOD%Ws;~k!yZVpqjHaHP=pDtY>zG);`DthjUxC*=S)k0hH zA0>%*iLEs#H%Moe%(+_Fc`gH1b8~7nx>vq%vemX=gK}pk`u`)_WkWEohU_1QME|?N zL@U36Fxw+)R}M(G_K1n4&TrhRWv@ajaZU~Vg9iOa_GTwFyytHa{Tvz)Uoq`-HKOT> ziN1&!QXdEB&e3#GK4SL^sXaxc5N|ti?|$I!ZM(oXHY-}M-#1%LV>a4O_)JiPrQ z7$kfU;1_5}xtCxB6~=5NJJF17CcaNW-q4zrrPU1<0mWl6brZ|4)6!_R`rEr_cFmaP z0}I5poZGyT9k{bYTY?Yfg5`IwJOG1UIBnLA!?INy3Z%o*-=+ZWMaUhyk-nv|3nMAx zG}WQF7**C-riJlx=cI0q+NVncje58J7~TzSF?mbaeT^}HVCjUH-7_;Ujs5K4c+EPH zB^*{b4jeaAq_$EN5xQzK(j`@fGIq@`10hsm|LW!Q<)dO-LS zXD!~ei&u4tS9t+D)uojOUEL9vO4=b`I5aP&G!OWZH9yVv+h0c86;74f8AgMOK8GMNUIMm`cge;5~3dGcT6qrw?0NZpWf|2JTxVq`@`nmfj{j z^0dTscHfi@eC8ij1(CuD4Di%iimiraI?Pw7xpNC;>$G+CFyJ|yvo?*H6jMG$FZQ0? zcRxNcV0%}cU!V7rZR=xeYsp6yuOF{#hoRL{EnxEGqYomljqt;$;cUneW`h&yFK3;; z;39VQ%NEkIRAydY{uMa%GY=L1nJkn1H22o{div#CQ>6y5HmuFThk*-kxpH+2fcs;3 zAd(yE#HhvBFb{oy?ryfSAVyM{VuQ~+^WOmqcM4NSqagv{43H@*jtZt zz;QmXq&i;E*b9{MPjgvJ)1I`jDsHufO8iHrGhsXZWCG)@`1R+w?bi(n^PyPGz29QA z{?TWQk^DcW)aMxyv>A}Xy;^9#NsF(T_N@T@58SuSeQsuFa*ZdOR*%CJJwfij98nKe zq`%Th=Bp>RtFpR#TJa|NC zrQ(oU0u1>5rxldR>ogWm*0fCXmYdnxd{5A+*j4w$m3J@p zw`R50Mws7TTn%k03%@?!H6Unrwmoc`6!I3N^rqTMIvGsr+MdJriFc<0-cOf3;r{h! z`wvmiiMG_QWYIbH^Dk5Lq045cmn_^IqrrtHnZSLgGL2j(qhY>ID!&qg-xOJU&;hRa zXXB^l!vO7Uw9cRP+SI+Ht&~M>bHuA2-_d;|n0wjYJSQ^$_b^8myb%RSg5=l9JKVH^8qt|o9y!dzNcQ+W=hm+36Q>q zRvEO;Ok`r)#E#+Sl{QJ8` zZ)2(UFXg2(I8>(lu5H*7kmOwb*_rqO_*W#|11A+3nfe^t37554y`8>n*D?RJ3&SN= zwvs0;@c~1Mg-t*8wG8VweVF%i{L$m2cEuiJCL`1X3$uKw2i@CT!n0h>*+oB`2Ys#h zCk_WtIq$*NxPo~Rn^)C?dio~RMnzw##ek-}nBtl~bVjN>0qiWzAp%yG*|p-LVjpJ_ z`IXplY|PQlS`9Z@++BWHn=bqb1K#?nFQ^tHLN|%er5UEspIDti(ukOo3KiaeSV}u# zG1*+@Ovx*N?ya-vWL5r1>hDZxnPOW*!xBasl|@Ywv~dhw7M;8c!*{0tMOomL+!HN= z``YIN)({;48ss#*To#{_X**gpw|plvRD!DBompi^Wr{)IS$Th@5ne_6s#1l5R8lPq zc%T%x5#`!q#~BHo##U74i0Z|QHAahR8f5Mi6J`c4C@@@?9DfzyvHql4Q`zi#d115Z z>y0>z9fD>W|4MdXdE^y>vx;gWwC3%nu^#vJJts*TLCzt^ zeD6~jJTtS~&Hjy=5PU(G%1&iX)4!_r1X=xj3cu963Ah@6vE2w{CnWc-uwc0V)N$Og ze64!@&8)9y(IS_dStJ(&gqSTE*}L-pEk5{nDG}7)j=V$=pZY96o`BR{+BZynNl%$) zvR^Zll~FMm(co-E{3h+H(`U2^-j_Pi{O)TO2TMA&reopAY*$J$&y#cc(ec*(>$@kH zj4+d_GsFW+E!n6Rw&Go^=)4uw>P{04@t)?t_#1MV6(o#ge0DT|dTyY;O6~GF@zk|A zl8`=Mqt4FZ8-hP;mx5Qb+r)9_U$2D-!8+IsAz%N(Ngto8+mEYH>UJ`A}<`Z~Q$(c3gp zXWRMT1!vasTyJMEcgji6c=EsSM;C04RaebXhF=mmC-&T+Xby!L{cx?mKTHzlImJWA z(HvL}3dAQ8rD_C#HDCk8Sn(uu`V4z>=2o`5wx?SkXYUMIefGK8HXQaL`?70d*cm1E z8Q^h(IJ$T4!sQCeE@XK*uU=gm7$?<8529nyFMk><&rH3D%O+Yka77JfQ%{N#wMrJ2 zwTpJ&tK=*Fse1P9b@)#o_cXbU>82yQOxGa_-|lU~0Hv8fhITk`y&0(Ns0>oPUS7eP0qJ3w@^U*T2EQwE>pcddyk zv;DiMQbhv+&5oUP;?9&o59?tmO>d9v{e>kiY2GZQ!tefwx1^As*8gd5p>{+nY+AI? z*$^<|nyX<(>U7~Y=2&?{-Hj|TsamI-oCd{RT}i&NLVS4Hp>Q4t_8v;O?R1{z^IC7a zkMiqaeUM}4yw+(SjR%@azSXq6B&kMYiz!0s_F6D`(6AXWuI-8A1JcwfUyBXO*~)ON zv=vWH$J>N7@!T-<QP3Jc|3>Nv!jWG^=~H1#CPua!0?b}P1|NiAcSwbv@ar(h zS~F>MmbKyCu#^hb>9`Tsffdt3wEF%T5*%IBHGjOin4$gL zrF(Aies`}sv9L*EFpxug%=RfJM_-!1x=JSXqf)G)BTrMX@Sju2VW}l&)0olb#dnAH z)Y{y4xI^MK-kco~xX-(W=?n;38>L>3K|_^njlv&i-~;i8(+_B0$#v@ct-1I5oulBq}l2Y-v=V0HJ3$>iA&M*-JO=QS<$Zz>TsqkTrY3ha~Z3^2(;B5y0U z@+T=5_)yd9GC(F}StprZQYrD)$e0F2kmQ2W6mZ_S*T|i~-Gy5MrJ5x~S6B%;KAD(z zds1i8VVq*(5*PABeWKx5k6|$gv#9+DSly*}A2S3hBPxb7Dy z5=s|-J>)jZF1fUX2JcXINNAFa@jg__w5dW=eApd-V~~=#0pjypA+?$O2;w39DMB_S z>qqKLfZ;9MiP8ByszHlqiVgg&uyZUuIn=|*=#G{xZ+mO{MGYD+i8F#D27c*?B!KTu zr0==wRU|yNBiCBC<~g+i^wtq+7xL97-MA_`)t#HQQ@>I^8+f zTWoJqax*_>{TIYrhb5JIH12H;rTRMT%M$7H@gE70itCZIpvRMSmZDZTBcvC0N%;UI zl{)tMW-n{zfx!Te2l}tzT07x6S9dT4k>jeW<^9^xEo9kW{4c)L`K7RK8@HjKPYf2E z_9Q#|5z<&DbixCoLWCnxc3s$9gNYuKSaFyx(Y;6G;laDzULhn?wdAZ&U#QZ*9?Rm; zlrs8hz@FzCNeI&GhPJ3U8FLtwCuRSc(SfWK^SG z)w#d|x1Rwc;#=1nF`K4I!Y}jb3x75A{}xZ9t6QzzNJ=@Og>$zER*4^9>nl@~B6bg% z^Yl~i2oxOwQzLgwTQx^o*NvMS#pcj13;9+ztnX-+Rh!Q*2x>_TJSa>1nxb-ozxCmq zhB@3bq|)3FUf6h}l?@Rr}+jgU>IKkC&UoEc&MkK@G`y zk~_#|Y;gJOcM^UPg(uoL2v&PDA0|%COTB5#jn%sL(#8e)jM!s;a2r0++Dt-!25nZ4 zTg_$TIf5{ppXd|8)ZL!1#}5|O)ej!_>L@u+FWX>FZmb1IT?x?0-2I5s^nLdBh-Y;* z=VZBJzNcs_=9#NoM!>c7&gAT}puuVR8h;2(x-7U;;hKq1-e*QfP1m$!QVEP=83bYQ)R%*=w-!SR#|P2V~7Z0(d};6 zO*g^5Of&!NEJc%l#v2p|cKq>x)jS!0&f;}F>Y)O{We=0V?A&sa1xgnA`E=oV;v9I8xrj4-<*1v8x6*?=$z?smg; zOChSJ=?{A^h}sH_oP6V&f`7I+o_T0L#PwdcBOtg7F&o)AAB?s%@07H#06L+7_fD4} z?{nTxDg8Zy3>6e^5JPLaN%oU=du3($d80l$0p8v>#M@HIMQ1Y-msgXyuT2{+;J^@RoEh1W~mB#l$JipD-1WV-rBikbJB5&csK)| zg{~O&xMV;MADyfWy9%}m?Ua^r&x?qBC_8jH+l`;vvl5&9RC^UK3TE2QBHG!A@of49 ze`+wmWG0SIw`}gV=@6aRTz5o={Wan%ZUzn1YBrlaR|10Q?GC&8eEJl;c9b2H`RL`d zWK5axmbeFX*5X&KANyCY*0x3{5!#J43NsjvqDp&|qtbmu(j7L}?~6B%tOD-^rs4Ic zqcMYoq~H8Q=O?#zvKPH8yVkc2E>+cS(t+|Y{yGxVi}Y@Dx@9xLQgP^#xZVCJ4+MknTzY} z*T^ucC+&t7{}vG0c1KTT%A%*hmZ&>n+|4OEB_+p^KC0am;MVI?_q&+wN3iY`Xk9eY z{EG*<94K3S61?V7V7u>5OaE_fYmmd;--+H(^&e)B^uF@U7 zhMe+E21hEwZ&0H-v^X@7zU?=?^d2n{f_u#Blk=CI&G;k6?;`!4u(kChHO9;Kd7g-I ze|BGPiCv)+IQ6q>{1cwTb2vIDI;(Mgj}-M=LmgD-63lyzCrGuFSa9(iz5djWr5eMJ z2>sl(5kCrY<^7XOd@-REgqy*C!TCm4V1jE8&KCZO&B=21$lw{si-L{(1UEwL5=q%nF4(8hw_@>HhsgV;LkcW$Eo|xu<6*epDHJjrP0!f9aDoo-P zh_5#Zq;6>BmqQ*ebEQnU0_`GhT@M5A0344NL_33SW7SJHqUx4B%*!qHEma5oh<`T{ z6MuaaKdJGc+)y&|MIX&3t>E1Vbfl!)GEbV-_?al9^F>NF;*)YyxvBZWo025;;#;+S z+MZ~^=qr_s_t9V11{E^6YMp`Cqd`>TDtt~pzfrh;*1jt?kAe~pbXccB$Y`NE7ZMOl zdJ3BNnMHn8van4yz&!_>$y+_C3H+y+%XS zQmQu!di*;2P*x{*gkJroLQa~}`R=d{i4H&)8YDp!&(Of7bWWTJ)6TWm!g{V258hmj z=L@(ubLVkOuWw7j)fC2J(u#_G7{$LgvQ?A9X;u7Rq#y~v`n1nPzr4o7|FJ<$)UB6HkiLQp`LEJJ8K%RA zTY3Gr*k{&_V@2E79^go2$|10-C8sT3^9&z(t(X1YpLWsG_*?B*lX3(X!Km-DmleDK zZPu;QQ2;FjbZ_n5FAHbexWxB8;x-S!(BtEd+3Rt5cJ}lNC6uaZ%`;J~u66w}C z_}^Ad!gw7@_HL>fHCW%$d8Wv&75m&~(bFQNm0*bjbRIi*1I;-+4cgOw*QNpmZS8JY z{@XZuaO3dyds0Q@BTu7rE=IGt*@e0K@?xiXqbwc?aWJ2-a%Y$gdurdGAzPgJR?6P= zc5Je)f^$0YH}1m*m0aCnplaoHSMXh;a4sRar%h(8MXe%-8cNc&hc*uforWYduOK{kY33>e{-u6^DlMHD3X4tFP{2tmcLDq zoCF67MVKr@(|V=>_glCjmAlun*pU>c(!lsNxS7@`!=D!P{nR7A&o;)Z{v&f4oew(4 zCtpP-mB3wz>*Byu5 zT@$1Nps4i0aATK%7Nn569?LxQu^%EfNQS^=F)1CZQ)Hn5`+^o@Tu?b;UbT@&m=n}4 z-K_|M?a}-Cm0=T;s?#QkjR^0%=uGAgTqfksi><2f89) zzBntvsLk7^CSvbV^LVw1+qDYAC0jHSE~Wb-rk9ye$iP4Af1|!ruQIr}pCR(E?~@#yq?%%f za==_(3sWUbBu!`Pqp)!6rcw1J6OT3?K{g_-ocVS?@DDhGInoS2ECujPin81sAgMlN{RFX~kJuo7zjaxlID@hX< z0jx$N1I65lyPhBR3={uNY^=~MI{JUlfbXD4mmO2;U}bQMr-a&P<}|kQgZ70>d>VEJ zoj}XmmRz7!WHFnVn#2&RDSz3pcN+%sdm@s*y*pj~^SuJ%%ly_z20Snou%fEs!Q#ts z&anUfZ(4ffQj(@BP4TmC7NTJPHRWQkJ?u@@58_}2v`+$eU;q6$~m?w+%8(2`QK- zNqx9SH%t))Kk97D^3aJF$}!uLc^;)Z^Tf6r+9010g)`yYX>w)&u>>BM&`5*1JGw zKpOpkI5~v-Ny2oiqt$#iXi@v~xVo`d2Jnb}MC~1)IVf;QLY<-d#CzBh6>&_g`M3VZ zX2(e>eWVRp8*Oizt{vH@K9QK?Kb9nHWp4NLCxUjpUH)aKw63u34NhxRl67&Ka-1G- zagK|bB2bjWv`>IfQuT3MVf>>$-9Izqp_E&4sg4nN8%Qe7CPHtrQ1rZ zGk(G?NG+ZuFg$a;oMjFID_MI{DS2{EbVlBhp-SO3o1PKqzWu|uG*jn)6rFWglW!lz zQBYJ$P`VTlP`Ya{6)9;!YLp;3V04FcgMff^Hv@?=ax@4CNOz5r-pG-^_j&){wO!YC z?|!~<&gV!bIC*|A_nX2`0Du}_A^v|Wkg?I4zY~V&d0OrHoldBvWqt_D7Y)&0Yl@CN zPi3$lg{wn-T%Q(IzJ4O_l7i1tXQo`b78@=1NGos`VGFUgY}68&Or$dWrE+X*@+DFf zejfQ%sY)z>^r@pdLN}#LIpTAEXwncUMOw}nnE=llZu?2E_b^fIKfLMurWR;Of&*^> z?R8CAM;>u?X;G(J!~la0%jQo~E*WWdnmz*?1}?^qXB}luurNa8gWhj z8`S}B57W>2L{A5xj6G18

Ra+CxD<+n(mo;U5e`4C*Z<7jhcpONuSo7E455y!r?c zJUu!uk;r-8VB*#LqUmqLO^ozM1`U*|EFBE_uyl4#OMap0T)w`Gusgb6yi`8cHyK}% zdLy9ey_~*+`F1(f7mihv80&C6}QLznt;0B^9=PE`tKQEf|c z)%o7h0F8LZX;p>n#Muy}Q?$V8OY!{9dG(g8L$1j5dN;ct7%o@pX?rZC)6|T8)t210 zx!hkzT=534Cs}8|NbTMcP-roe?A}RCtksR3kvL0547ZYg6;$4MefiA}?~zQdWt%cX zSYJ}Xjwqe4?$bRNTU{nbzx92Ni*c_(mrUoLdoiSGB5~>dIj~BvZ2G?r!oNT3A09rk z$$qtvRT<+lA}wB-7P^(nh$_nWbkP`FM^gMOep3N*PC`(9NxG=@w!*;qNIYHo=`1VU zsu*2l>l-J(2rRw>*&pYhnL#!QwrLNvS^A{Q-Vxeb_q zZ_=wupBi*~@qZ`$_oP8hCOH-Dr`0P%hUsxf4v}Py8@3)Q6CV*0^33mpfR#{2K1E%-3}_<`9?GRfW-pD>3tA}7%FOcWc$HR864W7*VX)$FqC37>ESz#x<83Lb7;x>IXX=^~A=ym0^Czp~{W^AyVWH3KFT-?i2`BiDN(e7&l zp`**pc+HJMfZv**h^5bx;4-6(J2G9w^lM0P(8u^z={*O(C!?RA4xINk)wPEIv9Y&2 z9{WxEBKU9mW06y$1yzT`e*ZEzhq`ABC+wo7OsJBbJqT42*|VKz|K{zJc2hO}SRtE0 zzEJ_u;`q~zZA3j{RLhSWk>RQfj1@^Gm)P>lwg}pdb=DI&j}&Ceb=Zm9Vc*UAOZJMZ z=EBE{H1M*qJQ-Xg_JH*R#EAXsT6db;b@q^LjvD`QoRr6TbU>UlssjJ+|_Boz<^&q^w5GZvc3I5mMqU1?tt$tvFbcCKdL%uV{)n{WVl#wxbI zb}etPcmoDfbkU`*^eJ_%SQ2VwyL!&ul_3WBk{J134w zbOuIH{l&`5$%-nY$j~(m{W~~TQ*S8E-{Baq#s4wU zVm6$t(<@!l5a1dcuFc>4?ny$-0t@1M9S0_lapgoy^1JA(tA9&|LMaJFnZhC2tyUt5 z&EMk4c%QOKEA4X`xK6ST#uRb2{j z9;-EneENwbPI*(fjdzOQz%}S9ZKZKd=jD<9OjR(%4eWW%40kuFYsjiLxY4dbxrQyN ztf_o_zhOmiZ<6fePCd3XW@G@ZC#?WMn|A{5WfF|^ zFe1&`wa?;X4gC7z9jRW5^86Wpki;&q_$;m<=9~#}?6LpMW(|h#OB*+$Dy12&g=&Z* zzi(3~_C1ZDu8Cp$uaof^x|+mB^6aq24SEZ=w~=m)<>|{|^~;N2rdf|8B*bUWN0?Y2 zv8>bEd53q~+YYXOyyhwAw!hCE0~%vL_z#a?f^jb|{npg5#%SqBgOH&@H;K9`W;rM< z;8dyV{wABsKtHnt9`E|VOHam!cvbsy4BhVdPda~8Ss8k!Om|f6u<~%ooqTt_O5Z+0 zvD(P6*()d`nh`$#R&Q4!5eq{k{T$*)My@G3#}!<1^rSzzGG}6N>-{p+nC3NYy3^ zE-Ey+EHbWCf4mGhk8S{3*uK#RxZ?g#O+navw*=VQJL#?}wdW5mzj4sY1hrlFfJs2_ z)^DHmGZ9VLI}~JX^Sl7~Om?^EJP-4@LLIS4nP;l`&`&1)Yqa%JZt)aFwJxp-#-7_T z$BurX9$!wl1yi|gXM5ZjE1cx$h0w#){^s9EuWZ12yGHYxv zNdgREs0w@fBG0~$*C|mbKA^};?AsZXnZ#FZ2BhTV>B}LEw0~7NBRcG8&q8qMT>fa$ z=UzgN19XSqjm|-1DcgZXQa^{!R}VAXmxT5+W3-M(TF;O@CC^&f?R&gly>4U`c=G^@ z5BQyePKN?WO>C&HjG{(~MV)PJNV+~aZTU8h4#$D%hH({D2DntTOjD(e601#fNbTT< zZQiKi8~r=h$tx?$8qC5vW&Hlo>Jsbcqz)?Y)N{09aaO6ild!X4%)ZC*R88o>6Q|&$ z>9)ZUhs4dr6Pq2D=`wURBfv$q%*vZx@f1?1s~ZE?y+mGr@DQDl%L3N${DO)r%SZpX zsLxA+(fyIAN4qo3PeEd%{ zLy@YL@^sc;ezRCB$CTMG+V{yhR)VZv{V8y08!i$}NtH2CCsi(dYY}$0D?YnP9?`Gf zGVJ;v9_gLX?tgesgog%PU!%G!jQTf+%V<)Re@+x|+jU%eovAQMPK)MQ&S1K(^;x;~ zzQ*=5O{x9k`Azg>KTdUy?UeH1(~x70?^tp5Kd&hPO5;>Zo|`(EiY+C!B-yM5q;t#@Gv@ZPwNPrmc>t(X9{2?8 z-PrcK+))qRkLws6 zCn?9AH+3!9ln=dUf(62)Mdi{q#Gb6Oz1?(_OghSRy{K*s_{tZmirqdp$Jwtffgv!G zo%w)xUI&m?>B5qikbbYoPra|io&*ugA{^f!%Z&ohY$X}B*UPMWsf<}L)V&9Movf>{ zZXan5J;Hr1hOjI4NE7oGW46#poepsc?zeb}55&$FZsXxH6gZgiOr>5_`Ptu-z5;4=+y8m-rSX^AHEs`MZYU=wg1n``D=%G7vxs zaJAW9RaI@qF8xeXG;hTSzO8;JEOp0 z6cjXfs8^d-l40}uNp^5{ex|Uh?0F9EY`vY>#FrX#*9KjKoT~yYovKsOicQhNkj5*k zC&#G|KGRV2IvM9x-Uznh0$5>G+=kC+(wI z$tICL|Bf6AH@F&EOse-Z0Q{x6(VS_uFIurRU@t3u6Jx~@EtF1rKD{?f_^LHAWF`(2 zDz@q*Hxf80C<7ps{^o16{tqV7ay@zg4Qm{Coh?i^YzhntOCVk364MZhgYJQ8cJo?w z%NK1V%O=lwUSN*<+J&c64MOuD&k%n9ooY|Js~P!kYApbx@gLrEXaEt2qzXrG z0;BeT`PvwJnoXY`Bc|OSj*q%}rvTij!^S3ZEj`LSAk=IDMzd#;az+ z!fu|yI_=jE46eJ+{n-GB7dmtrB)c{_fq+7!q@`4X&J}qs9*6Cv+PBO-4b$$F-m}(e zh#Apn!c6s6+W0g-u>VsKbFAQfmgUhc=Ffebak@gb!>{C30cDb`37Q^xL8L64LXppT zVd?9wJBO&`?O}H>_vS&OS3~_y+qUj>BBQf~p~+e=Y90jRBO2D>6g?(i zc&O zPhX!sBj3eiV8yYfwm`ovW%no=AI`^K&w3=ZDi^(MKbm)wVfZ z{zTY-8w#P`Wg^T>58or(^pbPA)Ckb$@=*}V*B~ae4E(^M^&W4{YUKFt>sB!AzL%5<`Qd9Xw$AqjqGy8SNC_6NtSXy9-y96` zoPSydjAQPcG3Xth4qW4V^zVqYu2i}JG~~oyAgN#uql+1G-P8-&#baAFmrU;gKfEDZ zhnNs7`VwL{W-cg-S^;MgqPGg}!^&{K#*~927oV}>&}3c=*oH@g6v}U;0Op>NrY~Q$ ziLY`yYKHecUsAzRw8Hl$^>gsV$5Mu*zWUv4 z`unLIV~u?iL~%`Va$}wAo6s=RT>SS-G01JI48z^{e|Y2|IVeyT_R>wKu77CCR&qUX zn59>q^I%Sq`ay3#(7|N+P)*2~<67R+V6XH4+w1sp$fCaOymZX@g?ksA_}N_lj%EY8B)6m5Ev4~IrjpPoU@A1NMERpxv^DkF zt{lB>w2x7YxrV&p#=STpW1?#|Puc!u>Dw~Y8_$exf4*rD5p&qhP?j-3jI4uRuPiTl zImrqORFA&&OU0?dl%cNIh9~+Rn-aH5KAO<_ z?PX`ji>qnaJ`l3)v#NV=ww7T}+Sjjv!m`K~iA3B^icwt^zHVk*=?u+rI9!0{1BGd% zF9>_l6+mdsM2=03v-8zt4=yzsY)DD@q(B*y)c*6((#=F*!*T%srMG3Hw2)yf26ixq zx%f26N7dEWx7UsI@bHO0WYx1zTagK-EqaxwFu5#_g8&EN?(z2ZCttyt(?@m=n-jjW z9`@zI)$rlPPm1vr1?Asr`k#T9cO6~ynHkNnR*@)r09$s{Gy2HHHqnzF{pv8(c_uxM zx`)VfkA=+{KjniQzUL}T-C!NOTDd|7Yt_6~G4#wHMltFCyJMXy3RlgLoia;y7%LoH zT+DCcR5aC(VBDK-w~uG=`{Ysb{83|6^pbbd}-zs3-xN`gRjro^S-66q; zOJ|9B=oT4`fAZk4X1H!`} zXx!GeidEsN(YoF3_&e@91-8q)Nk)@y0-iI`D?V;5#A&qI(tkmju$28-s9Y7`WI!lox-am7Oc8%|w3?DY9tDVAg;^UY@72qV) ze;KWfBH(r(1@1erCq|vNW6#71XYwH)4KNo`kbnp#7K{wM&_;%mu=8pwr}W3P>(D5_ z_}JkWHla7cFQmTbcFfQAy0t&_7r&vz65deM^@7PeY4pz9Z>VMMjjN*I0E8ocK0y*Jy}Br+0M-NCXXkBCT|$ zEH?>{R_8C*Cd_jNS^wZ*iXwo@q`Pz@&IJqj*&_};+K6@6WiCSO&Z!>Z>!h|TF9+#agGWpXX9bTU9%a%kiNMo-=(kT$qK>U`mK8U66M0DQ_Y>+ zoap~`A5ehg-s(;G(@UIH)7)10bKA7z-El7AynOLjGg{mtjp={cgCedaZpLu+ zirhHiTHl}_6Rih}TqcQDxtm3Xx*k1U;LI{+^?LNGfn8;)rNM|GmK*GrRSM(fkrrouQ`)g^459`0eDQLKwGVxn1lKtkDW190$n9=f%J^2=%-;_nstrS8NP5FccM7TwdymuAMrM z7x1)8CRTg2D^W#gFon3c7Rx>iH@l{Z5q5q+J0dZ#cR3UPb6`TL=U?~r$e$tH%T=vH z-1v&diH-%r!JL)8F5xQR;}v0#fv|^nh`jiE#)$C~Q2}EMjFnttxZc963c*F@R#I(U zr0Ob!lIoZ@?^WiChr5`a%+%_Ln%e$ZS>IqktHtW0n;WZ9-QrGC=_a`Pteo{;F6TnDX2E`)TSCNL`ElykYy(K4 z{Y6HY2t;dw$I2?ic0)aZO1Y3f-{0^k1$5M_e z<)0Wy(FUWc)gaqDHWyU~(F^0;zm_72yALkEgo)2O;4z@fU%^w(($SXbD#zuD3%ChD zMl&vzvvfJZq>Vp;DO-)RL8m`J=$#*{GxOkSifTd(mDt?>!{htR8(l> z%vt7eK%^4u#wt2?Q83Ch^*q6^@Dln=Oto;UjP`rm$Q-?$vnp~+YtD8lenCV$IZyFm zhQ^9Do$XipXQr>%E`hkV2a+9-GV8hGRNx_$V&8F*7ijv9&Fc2ehEhMCmL~Vqy7hsv z={7-vTB8kd$^NvIE)9vm=(<|m_yI673~++k<(}eEfZrrWoIPT1Nhs)XcRKF(IIV2? zxjx_6Dk%DP{#%Sr{kda27dy1(Wyk*Gt4S`?bH`EUIUROln!)Wu(ylUVC3)p!L|QVB zvFac|unJzT5?Wr;uVPjHs)cl<+52cJ5K%>P%Egk&oa$tfTUw^YFomk9#aryW|cu)g}dr z1dsDF?bL?iO=nV-R-g|?{JNBx-0 z%PN|{7-Ghf<>nzSRmi&<&Ekb_3)>mx=VAiQk9h(|2dQVO)sjbx+M_MTcnc=0>r1O# zfiSqEf_O2fJ`b-DSB(vOe0S)>iEgR`FTaw#WzJ?qTi}C{EE^||q_)UKef0{?evod- zvmZOH?ty=T$=XT?q;f_a(XDrjCFw2e zCzU;2u*|F`Uu9a)&Vn*``*V)j+a-Mn?~XRRbHC0J2yIQ8zhDZjyR=NJ+WRG2ymMjv z0vnQJ`|~zm3M#Pq+ozW4amRrk-Ap`)Hoq-%*|?};QRP7Rf`en^KRnY7JQ^laDJ^_B z0)xt1gFrH*wTv6aU9TgaG&cVb?csRyY_Y7LGN8wMJLr_2^X&1AR%k|-g1 zdf6VH-IqV^s%Ke;m=-CX__U*~Xh#J28tCtZzPPqJE|+)m88id&JFf*@a77&spg{jJVe3y!N&h+FpBj zElCx{ZotkC6od)+rV~Kib#X{C#-n*ANe0Fir+`k}5aesxe zanWjXdrgQ!!1GTzFV1LbDRs$fDB~j#_M&UR(vk~iwPjqHz?bF{f0*5RHLaQx43e^1 zn}!sj(rF>Cq74(YpfdVgnyoUZq$;Yqd|_F?sshfliCQei)clhEP16sK1%h6sD`f*n z)|Jey9LCJ3_1`Pu^Lc3PsC@7~id)CP0#RdS)}O>?137uw$ZJd-Za!yG_e*-j-|!Ty zD4+=^_8kHRA9NJ012jI(}#syrfdtRNO#d=izRRavi3qJ8|WxZ&~ruq9LqL)Uq-qev_X>Yn| zw>(aB!`lrQuvCSO*^X>)1O(mKxB+=a%rPK^fMPxPRA0&c50#;58Yvv4YAz${<~m?2 zM)l6~99p|mGCEHWowjD|n>W_c4xq;1I)38S_%yX~L2(+9)9Riad~2Zj0Pz*?B^fD@ z2BVcZ4|!mgdeh?)DARN7n^Ib1{z{>^EtF4V69RW}{qf&?XxsMC8XsAwO))hOt07HH z?eB=vrhyZh(~c*LGaoGSMqlP&KH=x?E;A$Tg;akv_)w8oet*x}u~WyILc@46j(S~3 z9A;;Jgbg&2yPF4wZ}onj-B2qp7+XtlZRbn3&&(bKaq700RL=$7+#RyYdJ+#q%atsA7`u8BX+}1Q1=AP> zxprW4eCR*SL^lC>xH>IFl7=WLFCbDn`RGCM-0Fq56~gl{I&Wd#lT>_7PxYWHt&opt zz22R$LAv5R{Enm+D8bxr#Bkdf^B!Yi>~ty&t@@rQ+6O}aTA5oX0>8%jp_mYZ4<72Y z$UiJW3LMssafHQLP8>|DKd`1V&fru$D6mK_iuF^2Y{9B2&$su1DcJ*cj7k5=Iiu{z zgoxsI;cp*~<>EFY2w}(7e77w?ra(>@^Zh$gU*jqG&1)-yi)oMZ7bZd7 ztvC8{c#L~!7>*Tu5V^Jz*8Tt`WYgSjbM8Gg9m{24Gh{szdk)g z_WYu!wpT3lkUf6LdS3eX(&xZF5*x@(%D~;ffof@-5}F+#cbWGtYVvHZ(0Z5Dh4@X*)p?{08ul& zGq&_0Ak~fkoQXPBzs*EQ2TK6=aN%-Ra#r6Q-5@OTX8_jJt^upX07R+;C2qTnj~OWw zY42WnY@}@Vz2nZnHYsm`?U?)`)$vU(25&@S*#GlSE1H-E{uCl2UIWLai?gGup)C)s z!XFO)Rh|oXM3L8GI4($rx{P$VPU1t(W4*U0atX6Ccwo(5Z{3b~94EL7JP!nbcgyfk z@bVS{7B-J#3yFiUJ(EF``NOXXtX?dUdTxa2%Qzn_z|{DH{>kUs_VJj$#S6cG^S5`| zurXJdSDA=fLA&z8sp6R4U6l;W&C`ZSAmx&TYUMY|;?5?8h(K)?LUW>UgP%DD@F#(jb`ESP5N^>vo8D3bLWJs59f4k!Z?gt8x zbgnhPSh*Q4F<79jm(ck)zam{=8cAb%phT*FkG5Z$MCv>RXNr1=K}NdCy0VQQ!9Q;H zEd|Nrn~q}1|IQ3EvEt@=T48X{gn|_EGElH;;D`Zd{19E>oaX(~D<_j$%chE;m=~jD zL?NmtiWht_?HG-Bt9%S5Hj)9Mu7#M*svp9Nu4P752lKPyE?ZK*!>s&^!wI7*x|zNT zz;~2|i$_m|!Hah8NHD|22=t!#sXi|^_u!v~2wgk!n}yGgxmL6lD)z(>aP!WOi;YT@D&f%mkw9Zsu7kTc!Aw$ypV(S>oUdx7jX0vE$-DdViS zk8V0H7|oV4Q!5Q`O*tGi|7;-tEEmfWH+c}M}4 zG%d&~&031bV-j@snLavDzXn@NDulNxpobtk)m0)n<5(*Pg)E2SZ6%i z5g{Wz8J21e+vdzE!C6;O@ESN6F&fouT$oOkG81iquPWUwt_Yv|JS zX&;nNI5meP{t>qMFeP1c+5>~6+KBN- z6h~Cpr?BK66EbWtopt(3W8%utFmifECLjx5p2jp-O2JwEE!Pgs}a$xS6Cd+D$PVMo@^c~bB9Evf`JQErBrJ1g0X6|06XQnV=&#>|-Ruv|P z|4M|0;nh|hzb|>I#4!_f%>4LVrewHuXwYUh1A1aH(_v7pL9f$r5F{uj^^8ya8r3Z{tvJY(ZG7pa%b#SRjBB)+oyN zULCff^4I*LXNE#!yb7`fpq-Q?`dh~TvYda*k%=GGz6J+qs$$V+h1ge{tvXkQWUeP_ z)m*B=R?d9JVpOK;#V%S9e$5TS-)T9Ub^4L@aDf};pVK$2*IzU8nT(^-SLB{7~Bk+45ynz0+L=MQbgB{+uP+g zUkeMg+ReQEQsnIA4r^<~hM|*HK8EF=dkD)s#a(oOYe%ChRjW|TAZ#n~{O9CrwqHBT zlnp<`8?9wmTmMvQ3*6J7dO;<@EaJ;|i@fo}>~$XFAj++EiE}!;^jy&ya_M`j$}yEg z1R)NpyN++GO>h+$s}IK8xWDCG&b zTk}Cx>->*shCiEyLA(G?Zhc|A`L&K3sK=QpGY1Llt$w_V)RL|I^Gw4?Y~tw$u%5wY1Oe^(5SNrKE?~lBz=t973N`>;a+_`zgW&W zU@9$9v=+~(e?xPdcJnMBXGwDa(TR0aRlDMx9CDMmj8kHEwQ?XUVcZ-256>E0 zUVGoKLox+!HbRg^h+=4r$5Z|eC01^yz@W!k)6MP7I5BP99(tIs=b5i{s}Yw%_;AhC z*&ehg?RkR}(-bVz>3a#mX*Jbtq(8H@vGi@;>2F`9=wU+DFv#2*eZ%l()#pbH>;6Kg z)#a_K*Gfx5!-ep+vhgp?3-`GdUuqLO^+}qQP{y2pQq(B<6VHP?yS6m2m7yL7@|s~i z2HR0^5fX#(qaM_&sjSeEUtiqFd!m#C7Wz+~W+^jdLnm)2uZ?gO>%LfIkUy)!YC9zy zU0j`S`ys$;&sm-z0E%?3EEDRBZX*>V{|?=P%_G;SlGl#r$4;}D)>S1P%0%ja-3Gh7 zKYFdP;PRV3Qhc4U;xFnsj!X$>zghq{C^d2hKUckPR9R#cBKJ+P|1Gt{`r?uCRDBIm zY8p{0gmJq&0M9f0Tnl)VS3mP?L0jgmfgj_7j=hdthdDGMu?j|kg_h(5DiK4$K|Miv zv7Q_UL)RaS{3n^D#&1-9bwe4K>LB{FUAeDfTOB@ePP%`7Td*r+yuBVv!MyNrrZ2jB z*V`f0ujJnh-DcLoLWJs{G5bGUp_{Wzgm|knzn!edl`PhrSjsaF4x7w-zMRJwD~f14 zX{I-`YtPGE-+n&@6ZB$`U6KvKCDsPZS?r-U#kg3JVZQ@Q%v~-YXrX14&-qX{{55m( zUsHz6q!X)e2))ysg?`;}U$S+3NEeE3M&z<`LWi0_F-86L@%;N92Zm~HzhQ5x$Py)t zOZWVAI6;7Q(1`-ESm*-G(c67{^TkQO$T43p7?+Gou3~BQqFOyvV71G10tT&x0^}(P z)I9M;?W;vh&#@v^X=}5GA~0sp{Av1%#!u_I)>SV^1D(x0l^EjGe9T(K)~h1@oYoUu ze=REh+DUhAkq?c(@#>9n+E-}c+6|b!IPac9(fRjY0YVElM7usB?TCARYw9Z$To3Vj z#_!H>6cf5I8*^5rcjI1zIT%N@C4|ZUkP}&W*Nzud;LYEUx9Y7cqSBpc7)vJ~I~sQ+ z(h~cwtA2bxB=m{b+@5aU<0VJ|+0={A0dpbs#VoE9~)G_Q&^wX)&E8EOM_NDR257%v< zcAX>WsgmKHt)(Yr+ z0%At83LTXwNP{${vA;k_C$XAOKVauxuJZb zgY_$}r)Gagc0WLs4_vO@NenO)GGaADKZAphu+-%=WPS>g%$!yG&i>8qA_4psY8EwLKUaR;I0ZinS8&lzS^7#sb#Y0iLuHiZT&iT%_gdp8h9-!@JyNv^hVIgb9xmU^Ma{0?jS*pnr<5l#V z@tRk#~c=(ZQu`8l|rY-``)|{u^v!=qr5-2cn?c zYsG@LlGYB(QNlQA@e1xekACt^2F>W<28F_3RYb$BAav)|krcZVXQs*i@HIJ(10Aq0 zPzF^hSinW23nfzu@Mjg^8PFj;)6bmPh0`A~68%`RA{X%E_SH;x8NOSfz=}YzW2fRn zT}Pj;7|zWvAVTU?R1}C6H3LUCql&HpQ-n9TYv~De6T>!R3^nJ?T@=s8wo^YGt=mt9BAy@(x?q7@PuGMfO*3Yc1$79?Rs7UK3e zPrm;6Uc-rI#^Ke|$2)t*qgcXoZ=C)rT*55i(Z3RFd>iBv@~?T5NEen+;U#VjTi1gk z#MNMK{w3lP*FQEl>B-#=H$+N6*Pr_v2t8yY=KLqE>fHXoSGMSGcz)6#E50|&=HP%Q z`;T0y^)cd?f(HLRyZik7KDzrkVKPr{c(4bkZHzVT9Zt3htIM$`wTvNQ448MFg!7@sYx{G!c;KKDVB;elPGOI5E6Z_IUz{-Ln6^mxzs5-HTo>o|wNi9` zX{C#-io=v^=xfxx57GUWMD^FQ2hz}y;a8rlb{u_f%w*;XRrZ!qXw$U$-(Wz86;;!q zB&_#ok!QX({9e+QxiJSOiawg_VS>Gf9KG|=ozKkQY({GDhFEjgVJpk>-1}Jy)2;Y3 zk$-HP+oqx*$u)E~BYmzQX1Ey+`7Q=jS*PkcgC|+H#_T!@e1Q8!Y=~r3k^a1SV{x)qT!Lx;bmI+8H zLs5T?d%e2XZhs;hq-fSDh^f9@H0~MbMtTt`xH0g*dsdAlpO~&QKBS*q66wjd^nP)v zszE!h?`1xevhl6tl>*ElPoynsN$l`zmL3C>3*`H}0zup~<}y)W^hhW@$j2vA_fNA$ zr1`3S2RhO0bw?e&{PAkolEzKte|X*%hLk~jt`}M#$E)~*X|JaCAVd;}OD=5x7K`;V zvv1!h!Trb0j_vwRr91?7RCI(6=GSs9;)IRhLv1|0DO+07lb-lEviEQPH1JSf_q)Bk zZi$GW!IbLsI`~5&CMiNELJWt(6rUyC+8PDl47n;h&Y_EtVV=d7vGxZ&-N7r^vU#bW ze61O21xQ_jME4?o@wC z>$x<#t?`by&M)r^B1)Lej@yf+(#SSj`zd_t9IZwtY`CBMME5?l<-Wl#jRF48bz|uY z3HVo3tKoo?6OrRS3Q^(0^CPvkm$5KaP)wm;-CJ>ZL$oob|GBOEhAH`ba^v}FkzXm| zb|En(1ix+0XFPQNNg(Uv>EEvXdP5YgXVy%P*vK{v=0kF%$LPyGw{KWRTN2_Lfqob~ z{WHj@+D?Bfao57(exi23S;hOm1MJxqBq3())-a6b;-8 zr_po1d&j=*tr0?s7LabolnSE3a@H5|+@`^wAdmbf!xYj31ibczc69I|y-qCs43+v) zRo;_kyU-~UZdr$hZQNB(S0F`%Lw-ZT7lfkw_jjyY_vukP2=F|7epA-i(2yd> zUEp~8Z@LLP^W{m?O{_Y9<=ic^0_H+3wa+7)c@k-?T)fclMRF~c!W(p~5}Q@>AeQ{$uvUmbFRR<5)iA*g2dg1GFCk}!U#$fcRA^Wf!Ktmvp=^9)hc zpUXzQ6Mo{o)nouBv7@veT!d55o}liQ^y`llUN`|6_!U}zOa5%U(K(hB4wh| zecHnSg>Z7VKcHGxmQqYM_V?iIH{3oMX81$8ppJFxi>{K*pZh0@MVz(J>rVy}9|tA| z$CT3c`Ai_5V;?M+_|Bvb=eIQ*+-*q|G(|In=|85OJ8|Flo{?J1dNNng9Ig|t(>}>+ zE-X6IOT`KWW`Kys1fR#+9z^XF&mSN{55-S1WE;`k!b6>?SuJKpjL(IP+i zqdy6A$`&qvKKx=E%zf(e_r5iAo^(m~Fgwr7;vf>OUgMX|-wB%1qTUZ?z6tKy7iVQH za%-kat)AUYX}3rGJ(ZS$Sj9Yjm&o$)7++`u9To7y=cR`}Lj^ zM9kz_`BOMUYGFxcMLS&6swoGKnAKn*w7Ae~{`i~F&?%KFGl*9JkVXGrUEA)0w zRO3(fq$87M>1AD6UWh?v24z&^nTg9;)`T;O`SRvXxQ_l@p&o-^sB{No&5jPA z?|ZrADR{%L=B;E)vlZC=%Y$}ifmaG!wih9-D!)9VY=i?y7JH#?mK3tK;eQqeE^7&Q zK09lw>tesAqPQmt#zA~ORwQk;z2_-`Dw?iR8K9(oCsiyd!ei~0^zcxsg1!P;(f)cF zz2Y|cpyeBXuAczJpSEp^?JsJo3Dxh0dcpL9jpOeHgAV0L%~}GiOr2%LNP%3-@uTCR zco(tLSzi2mzh~-U2f}UaHZRlB<3et%^&R3`bG4qMUw~L<mCWO$i<8X|KfI8<+Z&6b-=d=X-6g64eP0mM z4Xg&2dToPa?oKZWa}~(L8INCRHn%naQxrvVIV-`Uijvz&v9TP$8_FpCuLA$Eu zD?F(7FQ6JDxdb7FH`t515wcH$uLD+dPz+Ntz%_a&S~msXXiamKhIH3G|5@G(8oQKn z>gQ%99<3*JUys@=&Z->ImsU@@W3?qI_beU0Ml8{NC2M}fSU#O9WHR?6j%H^6lELF@ z<}((#YIehmB}|;po67qxmg=%;CrG)v=|k6vX|D9Pxx-3(V~w8h_Bjh7prY4OUs`Ls zS?A$6g%0nM*fYh-`UR8dtQiP)>H zy<{@9NPOCZ&ziILR!~VgG~fd>MpYfhrW+Jsn)T6-PY(NPx(tAm*Z^9BN+X+^XI77C ztnE8TQ!15RCcg=N9_;#eqko$Wpx;ve!=nX^5u^0Oxj3uNdGyXNJd396sWoJ%v`QQv z?e;fkKdvhv2scRJu4l%i#-uaWMG4ieTv3J~tF70}?5BqgKXI`#cF^ssr?ar2&mKithTE=q7WDQnS(ucXL| z^@ILx+dfYfihQYCNc7fw+V3Gl?AT@M6Hy01H!O(VNx!oO(XK6Nt$`27Dy&oCY#wx< zd(JP&YstfOUIdXHi`>5SmB#Hc_XW&NGrII>&KueqQ@1yun&TaoDf<|z9Uk9QVA{_y zZDWW49A|tliLyfbFH|jR+Nuc>trRjQbErn+sQAxmxp7xvxmh^!dh?paGibe!`PWJi zteX1kg!SKt+fv^;2>-)_8?E%uZe*;Y8f)raLp6vvw`pl_xrW-!exF5?;W&;0skM>U zJnJ_9qv$O7ntuBz45A=XqSB>ODka?@A|(Qf(k&&7F+yO#7z#);Nl|7CGcGMQj%H`8N=+{x6{5t4dWCm7w{p5bfPcaDu266g70D}#_+wboRm=4&{8K$x zHho2FSI*w-ResakEBnn2)Q+3f@?!of&{8abqzB?fG@H;sNg$RJi`}!w;K)8bE~jZp zN^#!awwJQ;omo#q8WveeJE=1g0OzreA%!M$6-$c?U#%k0BO@KJ87=KRARjT?9b7?$ zodlLj3*~OkCn5Y15G^-?{oxXSc9j`i^U1bQy&#VLdk^I3`V~^kw{Yj&@16eVo%#&6 z60vm_8Is@(Y=*mqbngwBA#TFg5gkj>1^Oykx>={gHw5`Jkx|zlMSpP~y@U19+k@iiLjJoQb#wlUWB3aO zmbdgjEz1wCIjlOLyFjSx{49&PH41JTES$xi*3@%7qz<36m(h;>jFVZd^Oc+=jH4a_ z38J`lt;)K|wkidY9Avr8=;R=<>`So@PkDOg`#`N1;LG~?;WdWhb8 zbCbIfm~XvzI!L+?p zffQY(2q`~1kJQ4T<%~Vm_sbs!L68bII&LJZc~rvLXxRdgk=FQZ??dt7WT1e`iU_xzd63nX}>}I zExqQ_21%}ayZ(}0km#wrkn4VTdH&6x07)B9-gUcD6=r!|4HlOSQY$r_(YXQ!6|Ka) zn+DAkI@=~n@a(PYK?*`Kh}CH?TRGl3|*-ow%xxv4m~Fm>qrhvO|8ZcvrHx~*^KmT2fL-~WnRRjF z{@CCc+>-LD$-agDMzLCnMXG310+HJnktG<_ktI-TRs>xDY^1zQUqwXq=r3s#&p4vpk|7Rr-e2UVJ?)_$^fV|YZGc0n~ZU$Jd~vndA$6H%X6`TwGT z0KOqZ6Wf@7>^~yL-ggURcwOp%Q7|RWedTJ3UbbaveH)rC70D)Fq2^(IZ#nn)j@w*? zEuNb-yC3s%qJK*V_W_qDu+`%N(Sn=>tp5|UW-eQctZrz*zabvrRWjvPaICYfdb*7As3+X6KI)tEE_dDu5HHcc38@b)&mB;N>uIf)3*iRy{*oU?_pPW|Lz-n5sF;aT0{u6JczfeD?tT@hKM=JWl2_! zLzK~X6?AwKt9XaHIBLY2f*ZCKUzP{0{MrL-3jz90y3kQpG+#tVoC8{Fv!QY7WW)`wN4yVQJs!a>{;1|ZodV|jeU$a zNn2rO?;aFmcC}U~_e>kXHJ6+3LD{B>Y?Lw^Goo+pWLVs?)Ryhh_s+iq9O|B?sA{f* zU^uR?ix{%0^R}z&{Gqt2>lEa8Y?`K$cxh<1UpeO6;RA27@g|rf%_givzJDRg$q*Sa ziP%}74z)<1`fB^9DYVN&ELv{%elB5d#A^uHv{bCTJbx1V!|H(-T@XR05=$N{lH}#w zGsi9PSb@PB+;MxZX~$Br8ka9S$7f#yD9#wTU83bA>y3P5ZJo7BZ4?UO!fBwnkQ9A> zfuRsdTfV~5J$;7IJDo6cZE;S9N4K;TNN57&(PQ)cJzTeHwk8D??0@gq$GAOdfK4ik ztw`IGe1Ecp^ zv-UbIM^QsOS#>K*a6YCgd`V2<6_R&(qse&0e51?6myJDR-wOmcPDzT~hG2szl0vU1$KEtdY{CShTvF3k%<+}lFYJ9hgC4DNid#Ox7V6H{ zfLN`Jaap5t>N91Vw={EKLnq68-8@uCthW`ms`GW-dp%XI%K>{2Houl#DDs~N;{MOF zRKLlD*PtFc8~p{R?SGVic(7uRcuA9QN8vWm&&`Z?zJLj?V`m$h>VLq6wx%||vDKxz z6+OJmV{g9B&Dk*G)f4ebNF97*d}93l z8=!z__dK{k6Ynhtp|@;6?YDEQFfO@&RGxhM;0}^X!+V-Mu%8ZKX?=xhtClT8PA7;N zmm)4#k1&GO&A%PNV&k^$2N~?+j|-rIwg+~!2Ht&wLA5VPj>JVB`Vr6sZ*|@!wJ87h zsDmQuFs>EI83XR32(VwiqB(ZVVkagwF`jmlP5eG@gJH85=a5ODkJyq+>yJ^l(sMu! zu+5OEUjy>|0-lMzmv0J@j`%6PsdXjGLk!O*Xy|@qM!0-Dx?&H*vwyh$u!0jOsvNpn zg!i;JNycOtYf7Y8<|B(bIE8KCpzkPvLvviV+56Yw3w-I3epJbN>s?jA8bjVk1)*ADWaUK zfr>b|2~HJlQj-gCr_JGw>Z+Z{k@>RVd)q%qV9=CWGrhniy9E|vq_HYwhWTHPF%Y?c)kK{(oa+4~o(a9)_DKiisOv|nzl8i^ISm(h*LEOveMg_b>Wq4>CDOhaUVdOB+=l7P#gP&28DR?7BvD;-2ma;G zdUQK}stZfVrNzrRR<-^1ctvC*2t^iZCAjuFi=-VcKTGWQOXc)_CdUhh+i;bk*{uN;BlFJ5qA0W<{&G0+JEk-Dwm=Wi%nGY zJcr_Dq`St#o2HZHl+UNLo)XVVO&w)pNP+pEqN4=w!=oN3u^XlOCsG#Mxft+KuVJzP z^Z=k%wj!2brc>+jL-%e+e+RrLcEJ{Xpj_S7mrVn%em~)IHlnQ6tc9H2q(*78z) z;UU}4E7;i;s+=(Ehw4!dBXHodG16L7!d_HX^i}}{^P_Q^S=NRo`PA)YG0_=53?1PG z$?zw%hz+K*RSjM2VQxb`P!k-2sM~;E@yK>4b#EV+ay_a|nnHXj2M-p_IVcQV zeAy03`;N~Kw+H?Ny1;lgo z$dqtpj?Pw0Rp*6!{Nn?^GdOQY<_9GYEGR_5#uIDy)+f;rD6t$Cv5>6!Gjxo)gth%5Ns;(9MdJ{pko|W+TCGoq7<|2oc z*P4B3kp)yY5)_8e%Uc3}mpHi-l-_?K+kfey_s-5hg&P0trrhNmI%0X}(k=J>v>2V$ z*^#AU!M+EZe4y~N^UmL*(3yXMb+GR~Yg`Na?WUGxv$;l*+Qsmv^{Mv8ESnBw9tpCe zfvlJq&bziT(z2ryamtYmCv@LgZBknOnK~3*IkX5p{_;G69=EldiFf@O4K1&@76`;X zNffP}9Dhe5P^%W*N_J1jbWZFXuK&rb$L?E}1M*j#2#@6@skEi+g(@3A90+tNev$*4 zUKtX`nnKy6l5~Aye#3Ed(q&-3F5NnVrHe&f>U&EfT*PBh(WK1C=D#Q*W?s9wdO&{1 zy3eUd%SqhV4OtUF<<|Q>Ns`jl^=sFi)+7+X_2q{=_HvJ=&6>_l)BR7dXMSScesd}k zbq`dV%u1soGHepv`<=U{i5XsPJ_W5isIWNqF{PeipBl7rQm!?!nMR&!m@c*jy=nZ@dd22JORG-D-JhNJXQ<{}626Ehr_jX0xI2bt7W)+Aef+A(^>8izJfO0I&D$G} zn_M&zeC=@TD!c%7N#3Jej~uV}pUb}CoLpIvWnys;Wj_C{?r}LW#zx#1UH^=38_9lK z&QNN$q_d5Z9y$3;f1F+Jq}g70Wq_=k?QIv|bNcgsZoE7u?S~DaO82zKRzZ+^=*uAz zt>&st7OC~Mv@uIh=t-^Nop71;9f0;wQzLBec|}eg)d}fR_S?|}dH<+}kVJEH_0rlP z+QR*JmiZP>pVGCU0cE^VNPfD$ZE5tK}`Q44P0LHy);x(cX6PmwZRZ(mYm4@8b+x7fsa61mMO4A?a^EGNl5)iVhdCGD^6Sc+5zIGr8uZrxBtV%1}1Lk<#fdOAIT63 z2;pB60;rj3ioJ#Jvg93W?81U%$6H@PM-#6pzUl+d(1;T;lwpMaz?QIq|1{mel z2m3pn&N>_|AyQaP&+D}WwJ+w2Be%48TQXisdGw5_=!%zB2mAUCM~x-Ru$~MF_6uVOr zN^NY_`;|97DlAJAzH6Kn)5Pvf^ca*35aVY;er5)Y`c!8CUx^w0=2R`_7ki}C zq%s@VYq;bSbBu0I?uf5X!F(SL5!XBo>=#`$+un3Oz7T@bXY@^?>t-p;;L-XSN*VqCNGT&uM6tYx}YQdfDhPJQ1^K_uenCCHpNrUpf+D2J$Vyfx6D!hJ>=S3spT?xd&+( zW~{31HQf6q%fVyaP${fMOiar~1YMZz^dH!)nZNv}i1NtOhztA5I8Rui;)`#GN=)EB z!x<%(y=tZ0+?EYb^#Z3yzID82&ph#Jq3Wb#mU2eo#FCBPsb1*?qItSDeW0cxQ%E>B zCOWQE9<=7hmf0dt`{J-K7|*gwMR`;Z`VX^UsVccKD^B&(EI#}BPwKT$J-w8X0g4lF26k#I)7(W95qkD->%{HR)3@u*>ODB z5K#pmoyT-h#*BB20Wl>KJ8$Rr-N`w!uhLAm$A!_1y<{ z@pW>1!SnGa>?9iOC%cjJ!9Q^Ot0VsU^$j!1HK&>0$7?o>DYM35L#d>fuSU1@ z#YaWcrZM)g;v$^bioBUINF=AuY_SyHVCzlYs=IVeHl|>>9SZ;2Mh$kDRlesWJvR;z z&lchdzOZy%YfMFjF!MxuN30$it%XIH)W$fYx)}Ysl#_&}A_!B_t1c?vGqA9vHz|0@ zV&Wv&GQF@pjUo($6c<>^Q*zd0*@@N|$~c*OnqQ3-8VkZ(0Huo2Cb@sVq&g%Iki97S zhpo_6$}kKJB4(z%bvmj**aQ^masSjdi1yX}we!eBQQWNcL367odzvmRSzO>3$g%BJ z6~b2LZs8HF9^bEc@|bmo843R*;gvlWzI49>y`TIJ@AX*DiY1jF>|Y&sv5cQy%NzVO zL%?>Tv0fD1rJR1V8?8(;?qpH&-G>f}w}oq$UK zRo}P5PPCKd8$bW(decBSC)Zq^WJW#w;%*EMMXv0dH&{s7pD0%!raUNksqOk9!+)z0 z6=Fq2^t}YK==c-&(i96_0mZjial2bA|CC$~#n$=xnuPfE8?cVyraBL`685P4bq0#e zi$WSYh5-rEq_CCR#z&?HPIp?1%S?B!z|ne?K^!A(xAAb;jG+<3L2OSpGG(2ya!oHh z?eCNh0&r6qs5sJQnCPtKE)ZKbRqF*&nB!|asC3U__v%pWfHR(@ktaZ9y5#*mT44{pN^ zoIMNmkk4fO1gg^{pDtHGB?v2)TxM3`v*%I*ZUdW{agXG`%dGnFoZ$gYHxbIK@hBqM z;fuDAd^hV^^a>@0qX%s!m0y%p-_&wDrgQeWlGEMWkZ#}r^GHC%wH&m=L+e^?5u%CZ z%PuijEzoIGshj06HCYx--Jt(Lq{TeuBD4gIV7a@+Eg(X*t(9#txeYD# zb*#Frdpugi|I5AFedGJpR!e>R)$3g&8nHal`JJ)HO!n>4(HoxM{B3zw4I856zCYTN z8v9KQ)OBam?1-evNr%<0Thif195H>WGc`A6Z)TF^71gZ|;zDD(t3)j+cYLoVp%d9P zN5QQR7o1ED%h6Nql=n#r(RLN<3g`v__PI&3f#;-Bzh;9EhmM z4^?}xR>S!HL~zbKN@LGcy|iTsI@s zns7iL+nn|C0C1vx9z^V)Bf-_^l+2r)V)M84pe=>th9&m|5{{pazpv(CL)RYx~|VRJ@CMpLijRT`=oAy8Jj;O$ zJ^~XX?Fo>)HX^EJ4ZVnA^YXKjG}4AMbjZzXmV{6Ay(V)$|9WNHxk3S42Nxqlj7GC^ z*=~4i9DJ=UBugSzf9gzLAP1s{EX&Cd-|(>F_&%cC2fd4-ILyV&25{-uP9aos&4qbQ zNF2WR@5q@p$8OFMmscVP) zec=_{iGIEObuw|$>j1L2E+TNG6PpsMKg?74i{;sj*=ZZlPjYFuV=KbHT4RBWF>rOB z>kh8EJ7EcD)r(C2ZY!ef(D=>bj#6K6?Em4pR(Li8OzfI&J*XHwWHhVbF4RoHc$-R| ziTipD>dm?MP4e{U0DEmi#|eHqd;Otxk}nPLHO{p;RBDKNt<^Z)!XQe!@B(w)6D8Vedld2tSZ_y@md+I z-=~5hq&iBKSszOPX~zXWyp9yz(j>o4REasrjHx8Nf~Vs7iw1t02^C9Jg0HpG=O?KQTApdS{zsy=d6}ie z&oO#Xryx(bM}=MQLJ>{LoiVC!TGNRDt@FGsGaacx?1Eq}#Zy2rNjpo&amO~Zi#zWvCMmCGbCP1|4lWAod$^c+X9|N)?UDm&7j&iI;a(o0G9jW_cAuzwvYE-q zWF=RXnenOte5FOZCoh?F-D!*vEfkZ+NQRk6C=#OtYgK^mF&VxSn8GpKMCWW?)vycgVZ&F@r@jH zVe=y+f(LQ*HPG{I)XyFto9>~OEdW?BA^~uY6~uY61G7qKedRT8-#dcd z$KRiB<;C5*0xGN4%nCno__QLe;Htqa|IJd)QSwye8}Y%{hSOJ~!RUn(OEBr*xO%Ob z{OTIL`&KGG1tjl+=ym>NC0`6Hp(zQ_t6jB@`?{@I-2&x!U* z(1;P~5purnoMUzIF`}ZrpmcjJOC=aA?;-a<%zZa)uXc=63%lKi6w04T&Ia&@;>CqZ z%4=kVyIk#{`FXNDmFFdT7&=QVsyBwB-Onjva)0@5E*wuEgRT|u^(>!~MVg$TIjk!bX4tX==AY8)aC|A6}uGR2BW~|n4 zC70+hLUX*u{Y*Lp2_e#Dx`&HNd380%WEM|}s0PYwC8Fsmn<(>N;~3Aat+$UUY;0}} z6h?N=$R_w&;cV45vhbt>6&Jl$WD5M46FnQw(&9bFCa=M~v>^qR^b%n-e#2+IVxB_Z-K$FLAtMyZt&sHSP~#jjg%HC+-eE?Y z1JEMWPR~Y4RDJ0d&V+ch*h(}9CN+odOBb^2kpo~j(rYGgb`O#R6<*sYf)M|+OAY+< z-1)@Hx&H3&n)h!IaleCzyNviOa7F+4MjqNB-;G3XFO_(4DxFZa8>q zeLi{6y<%(>%Z0Ks4`gstW+e#s!3krgVPV9#SgvQJp1e{NUN;VvPp6}cXq(DfQKLqgulb%q&DxteYrT7E&RfowQICHZMV#Z` zB}k%{bbJAYL&aa_{JdI*FK?zAZXYOjTBy9cl7$=M(y@itY&|iLJgt&i5Zd980gB-~ z63g8*TM4dAr(PRkZ4)Aew!)QMu&fMiP#P0jOlk3Ze2<4Fv84;)_z<#6c`T ztFcI~jw@motp>ZCWhqTZW4tt#FS)lk-K%+g=|pYp!W9Y)ieS8;hTq=6i?z^Q?KAsY5i`PzUuR{tE$-BG>mH~0QF|Kb)_D8qI)GW1JzuBEu zyi3b-9`~?7iZC&;a9QA;Z*pC0!FUtNp7UZ5mARQpwI@)7nT3Z7!4WKTx(u5+VLJ3& zKa}oG$zp1qvi)hXxNx_^)I?#(1}`!@;>b-)1L=UN8ktVA)Rppp|&tE1f2YCK~n57}2s^q!liRI>aO zG=HhZvTw3>MD0_RV&Fc6Gw*98bX#$NB$Vgj-76fJMGI9g+Y-LwiZXrZ@evrjmcqRD zlte^UHU(DO4)Md)mrHjW1{=iNIRqa}HCNnvZXk1Whj@0X96Mu~wET;~fBN*RG4LP2 zq%uhw2Yle4kp|Cue9HcOvPcScPJt?H;SU9o^%&)`+BxB~9ha?Z(FWs$707yN&M4FP z_HoI`&tgfl-+zzwC$e9RxFpYw79X$8CuRhXsw>~S&L!MUzkWA@X+wMGteH?Cc^Z2sx=RHh@DKv(8 z3jRVeN%LRo4GR=$Rh2??xUJ?XS5@u4-edAF>dpPV=d8Sr)Gu`6F1pQ8Rv70Y7m2@j zQ=n{f6wXzZ4Rf4Suvxo#J!0!^ToJ@n+ho2frm3V)SKy&2aJo;RBzng0m{t>g_;OyS z$=*#Ht2)Iyp2JTf&uuR%4$R|<@`p}%j>-U0aptbdKJqkg1&-3A75QhAv*U~Jxk$2lS*thotM9>KzZMXPb|{9# z?|Lgeb_`Y2AMaLG0X}Qj>i)&e^Dy2@5~6$a3*t`XxYwC(MbKYZ#P0g9b)qNO1J zkq93cEq_X=+~^fN%f|6%A8=q$=b1N2rt96DT(G%rBu#Jrntqk2iOy=H3EJrufhStR z`ijh?jjAS)7R+@14VT>H6Ld-p@tjGn-$3m#rRWPXju+VjzA$-Hhq2tIhMkQPMk%q) zYk?g%8r{jBCcA&Z!D!Rn`uL^JF{RiFwHG~2?kmr4!)WE<4e&3xc=S=Ia-|1=^A>j6 zhw!3d&e6i}oaJym;Vy`S?$>8-3LBnPDR7V5nBiBA*IB7+V-!f}F!Uj!1t`o#wx2AA z9x2vwQ?6Ny(mnhA4Y8{!oWa>lt8G-~K}wl5yIvm-aPTCf}~B^j4$2O$Rx`!AiuSIYHfr+B_kmonLtnf#@`fm*To#>NWKe9F&#BgoJXh8htLe3SR{S-NHMMT(q5ju=^xz~*SZcg~kxNY#m zKJ`eUqyApr^8?w61jdQlsG|Q!e0_W+BKileSI+1nK^3QCw7r!`-aM(pT6?lMMa{g( z_(3{K&B=kg$A|d(0nh0GfcU3L!E%u;*uK8gBicuH83cw3WOBOV=$3y}X@t=W3Km6N zNywy(uVF9=CvmMvv-R2(gcw2+4OrFo?!748Rw6_yI%mSIDyWo&ay z_dOV>#v&!=D{jrjO>|V=;LuyqR%=qBHk2(;sMT=nX*I~Uxfwys~1DmotY5IO*Iftm4F9oh4Vj>eBgZd(+E>}?^GKX7M|5l50@Cz z)P9*R5QT-JPkiyu6C6j*cfF|l?wRxseH)3UH>mh}*6@kRG*@%~BAK^u-w1SOA+uPL zm%=m|Jm^g^e`O%c*9tS?uAQp897@m}C5ksqL!JV7YOk#pgscq{*^)N7{IMm-&5L<- z%tk8Is4wOI^`Af261!fH=8Pg91WZ2V63fPx-Wp_iQ`u!NIiZ(nM;w`be5b~i-v3~i zl}1Uc-owWsN;QDK!7h}|_~BL;-7mYDT|qc+)d^2SD8t8~?~S)IpE_an2uVEk+SSZ4 zu`31KQhSqHQcLDmBB}g>mF%CAS!B=&!p?)DIasI7eE&=VQIRPeVrdQ03o$EFRsE;IW_J1`S+(Jy59uN z?rmBE8inb ze)?-tulC(s%8U8V2cH7y{Mrh4tBA!6k+ajE@Yvd%#QiWWZqL!|vT8~C+%j<^BIQf` z_hmxB9tfv`Q2UQW2}`KWahEC@S09``f7!XHK6@vuSW>XLC2_&$d{uW7cl0 z+EbJ$Yl21y~!OF_ORYFi*O@vu4g3F*PgRAr!4|KjDGnS|8J?j-iV>m>xcB( zUYjFN-x!gU(w4ZnC!%V<5~wk8lV3kwd&TsHmMO>?qPKMsYQAYq-p5NpqUix&;RY+5+?S3to6@cr-}eO-uk$>Mjzf3NztT2!MuF>R4;RYDS_QAgn) zU#I!``V80-s-*OLd>GjNdIVGfOz;}30j%URS$*9~JjuJQ{EnCNbzYyni;T9l<#7=Irn1hj=pH@W zul_FWC=8;uX7;=$K#H-pw%UK-a9W~3t3LV-%dwl^_i0ZHhqfGCSg)L3rlVs%&T*jr za6I>%cp|#hpf{ zN|((JjUeB0{MI+e%xUj@t#)eKDhHMC`L#vlOqCyX=4VL3uY0z)*h| zB6fg>9pl_Ga}*5WU++KMtZcv<%(VP{?(Za^wK1r1J9@oMmg_CFx@4b|4}(YqjPKU@ z%-KJkG9ii@O5mesWYN*=7p2_AsNJT{MTk~Y=#=i1#EmeUmmMNuDXydURmVTk+59;W z2=63uUT->^;@WEZXTW*r(FEPv?W~ahNM3A|^G`S=8jc?+d+uZF!{<;*0PDr#1`#PSXZb1TKmD*6_1Yrl&%#H_^T?@AM4 zv?Z27z+6;Ar_6xu6nP0Qy<6kcWJT^|vi45Rtabg8R{b*-Bt?tS9PlfOMhgV+&2=`K z=qFir-7J*Zb{vTlpOQ4{QF_*Zu}t(YD`SNQZzJChQEAu7e>IRX;#%20$sdlpG@IZ` zP`Zl^EnbBqUAMNi8yjm8W`Cl0Pe6A@4N`I)$LE&k2%?zSP~j;vtZ-`XPNFub!F0&4NXM9IK7ixXg0Vp`@o1C@JBoR)oSb$4WnJGuAMF^hmC&xV%?Kt6lCr;}}I*&Cbj$;B>b3g89 zGvaO5n#nCpS4PrUh{Z~L2`T*{qN!P=e$f*2Y8elT(sLE;uf9j8~Qu@*=bXty$Oe`GY*Pp9*U;`Y;GvS`~a z{#`3^99MfCiu!avLYSu>k^WvSTuXs8ZCOLPng3s<%m91b9S`W!>QLZkL)fUy1*a+r zYp#gg+(4v_G-e-k-X4E5swC#&22QOMy&BBFq>C?Z49h`p&{`dF|x4gey z79a~7dw94`!@ZUc7F(!kkdRGML!0@2uei5Oy696X+KxsX^(Z~Ank0j#(51)!AluX{ zhRY#prWNebBGn6vTJ92ko0=)G7Cmdl{Y+a{Kibw0asYpPtQIz1n$LBEV%gCVNRnFhE?ki2%VW{f!%(X*Ksu5=s zo>rJxc%|}S-jxp?;3wd#z>|=v1c(xKOXsmh9gj8euQavQmY8ra@ z)T{wnIcwU@`$9qw1iZ38#R1zdVdJ8WvHTbYx}KxOF%4X$RM;O}tm?Gw#Hr|}X$P=G zT&Tgt^)dYrJ9T1W516jIEu4yVNvM>P&*fhV*B~PM+R*7tbK~>y@M=PfQWE_zuYZQj zaOHT4fRAESZ>tHCU&_ZqfA{2VLB7RvDIjEt|19!gG_Xnl&4#T?IRU=B~y0_w`$Ix(;R zBavLB1}+7V>r%YEd4H3J7sqm&;%Ex@7+X178|vQArAYf2xtI3;rvCX_rF}iiZ>~PL zr}KS_mb1HIF3&-HK9;FBEhUP;+-Ggqbgek$o6wDVAv}AjO}ot@K8c|E^xf;`7W&!0 zG?~NWG*C39dc zYx5xQCMDXw5vV7G&h+TPjyjcEj_C*Q=|uFKd@c*U_x$c`|7O6VqR;$GwfU}(yqy4t94lR&79S2n%bZj+$5XG|2eT+hGtl*U!Up$1tq>v1eH>b!W8sN50x zan7ogR5-A9t;l!i7$Be%@lh}1uX4-J?~NH>S$I5=4N zcy8=^k{_>!RB~?-&X4kKA;wr@{EKo3r|=}6-`|NdA3dVGV*J_H7A7z7h0NM@RQtiQ zQf&--7i~e_Y>tAY3aV=JG!Qd>rI&&h(7RWXz&rEr$w_YIYb6Itybg@y0#4inJO4)# z?f1@#M3RQ0qg4zuvkYIzgrAk`PHPo8)79U3Y!J=kyCXl>m0cMULmW@XNHx_p-bDF+ zNv>9-%k+8J$9}B-fybVIYhKfuj)mc0+EMSdRfzJP+CXaDx;X~e8}WPRcz)Lp7-w=+ z+q{te)l-!Hx4t$L|2I*C$lec`nnV6~6ci@KiHcg0pjqkcTf`jB{g_)PeSQ~FSI2EzK96x%B;5+gNZ%9KKKWP9ZXygB!pa#w>yQ37k7S~kl7!&HEhAUlXQu2FZUSM#ASa4%pPScFko< z5{jjca%SG9Maps!w`=KZ#kkb<*eFgO3_SAlOik+Jsg6eNp>kd9FW;xPx%N8O6TdO2 z3+#Zt`Sr%Hi3Izp=cAP$K*X_@2&A2MA=urzzP`SS_vM}GMd`|SFs3$rXAtf=T~K0Y zAh|%x;kxnW@7vfdZkyVJ%Q9RH{;$qlm-8Mjz4Iu$BGgnz9vvk zJer)@zmev9lilS7iq&ME3Q_zkPCNsGr2SV$G%-gxCv71FX(aw3@fjFw0ay_Zq(yzH z_pO@+B9wkR9Xjs@-}ZOU5GGaB8snM!aIFMgXz~e%DnQ(@e6{F@YdWfZbwM;w4{gQD zgLwKsN5lVgMz+pux78~jj1{jyr&gXLFe0I@{}e>dD>+(*pH+7FyeN7w!sn$QeaJ$CYcien4LmW-Q6Dv)P}K63UKKM#lBQ zN@}@_Vub?Fg^rb@-j16C|u*}B&kD_z` zXYzmJI7up}O3sH>NaYkc=CDc;Le6J$$Z44Kajcxr3n6nVhny{knX{aevti76M2>9^ zGd4coegA>|vitGA-}m);UC-wy-b)jQTLZU46W?t*&)Cva-gGvw?hO$nz$|k?re?JS z-EY2rXj100Pp{lP<;5z@BHIW**I{nQVA2DQ$kpXblV5Z7UT4!hvAauZ)Go@!I7ptfjU$;bZDV-@e#1ao4Cm|FS5R+_Qb z`a?F_=hrxU&VhZvI#hzcj`r&Lzi21?QeKH`I3N|P(SebDtbx^xHru!--)#StZux#4 z1T~J%o;QS_$GIc(M2SXJAL}Zw3z*`M)4S#Jls}{Bj#K8Zh1ZiYhBG2xEMvyrAC34e zqilN>+cXhDoL!1~ypY#u*)3axR%GoBto7(Y;ef-{>va8G4k|2RqMNp}|A;wRE0Vnr zHV?nY{C;=0`KI^1`zx9+eCW!#8TfckmI2#O2l`;_E~TH_FB-fWTFX_8S*N$bmu}iW~|pV|8X07_tsL6ZoQ5a zaf@){3W4u;mD%Qoe!>RjTImjOHXqQ0R#q!_fwHuT;@32$kl9t=o-A+ITU*5oM=&{7 z4tl{d`8lNEgifp}u^XmFG7kLadhx)PhZ@s9UNCbzTad#kX^Sc*c?i9Qd>c-awp$m; zIQ5=s?wo@W^FKpmRXL|1#=)!nTBEY4$zwA$&Fe3(*DUlgoS zJKGR7s<+I0ZBI~>z!^&=nLR8w--7*d+2s76`9JJDgF8{7cPey{`4W62{G^vesr5!v5P7#T4D|VH;n<5r=j2c6MhjW zC}8K_%(ZsC=u)AK>5KMK-$~_Q!cMRADkfgplwhhe;c*0I&vWCyG9g}cF)`&y-=m)P z#34ijjIvMt82z)n(-APcx!YMQnXGzGEl{9(4a`Z>-Cxs-_Pht)O$-fQbve*n`v+uDEV%SjZvJ1AoPTekh(6zWR19M%-XV_GbX@GsR zpuRn&9B*OSPuPs#J3=rlndbow&`0FsmbR&C?aKBxJ88D?aYlg;@bEsH)jd|<0_tlg z3i&SqK9JC6TnzO9(XC=)De7lWI9*EH+U@wK*W+S`KdFDvGS=11QW32pIglBGBy^N| z8!d88o_e->6L_^_Us)=}8_eJ)E%h2yvQ6ASY>o16F!zU=b{FsiJ^tOIsGpZm-|swN ztjxn2IqYnYOEQo7TyLSm9sTp(WOj|oW~DJ~R)5x6dmkCZQ*S*2fqzcp^yywTbsOCM z=?(Y!#x43*CmA+`kP513c@lpK7)%FdPzpkvxUM>zkbUOi{fs`_e4UfZBq*{Gv|t{i6L z7`7KlxU|z%=OT_{Hc^rI`&&4=!~?ORdMeF&@@1Wjnfs512?*-E0RfS??%~@vWBgfp zUXSbGnAt2N?(-ZG@xpDUsWQ3TOj7+x#fLv`&eX`X+}Th7%y#xs6XtjOTzD-BK}@uk$H~XFJ)|Z` z$=@qOR_~gPR)XK1q)BbX@m)F(+8IOu&NDgy5G#@-0ooh>plJdETsar%9Ur+;QU+pV zm=mwwRP?^(Ie4nsEonvjh7?KmCTVvqv-v@F=h&^uDHuw!pVIk$0* z;K-ZP)oLqgL@066HB!SfZip(rdLTs|Mm2UnKjiH9COMd=EbGes=(F>7xRW_IPd7@B z4p>WLVTN#0S2Q976bP88YCqUz(y}I%|LiWgY=DM)Xo*@5IfoTV4+uUqq1AYk6q!Ke z2NAn4K?cTf9Do?yQq+3}$4bmLmHh6uL^yx?6kVhZ8< zZ6A0U`o4gwA*6n*{uOMPQD(-kX-(#6O(cz@h!;hW;zes6Zb6?{oq~}~HNaT*L)+ao ze0^U5Gt{jU%eb2vqMEo8#_(2p2cFzlXmuXJ&=G*re)qiRmppUPR|XaOU;q_qfMxEG zqyX_F#R89DT?MyP1!y^7VbsF6ip7MZ^uXoV!a-g(BQFRv|iB%OBv-O11-6Rd3%1jyev z7Tcf{FR6pJjQc)SQ!=)`v)9FlfYQMf!!= zkTsF=DB!!vOsB?JpKm^$iwnP>`rm6y$3X|i5&>Kg+4p52j742g_yM7++D0MC~LWo%6YdGQ*9GF?URH z5RCW>AKlqS%+WO4z=(y5cP3Xg7=l_BJ%nhu3`H*Q56;7IRckL~j!SR1-?W+NjL!#? zrJ-Fwhz?no64Zg0_(tqxbZczUAQpQsTA=b2q&0Z%7)EAFr-W7R*?yqTrJ)olK%5}H z6DFbDt~#&V*5DM|v!q_iqgBjdJ}~S>ZG}9VA?cCzNJ=;q<+g?iAuE=CSL*qS%f3H% zVO&F%U|T~l!)L{X>_^Z38exzS$a!U(JOP2bC<%s0Y)pwfgpFUsj_8Vd+z5f{L^**Ha318rkLB*zI(?+#&1EuN^6wGPzxbs@$ z7i?6(6PtI8F%7Adnoc=(A1^P3tF;{tx0ZERo8 z%kG=5O1<_?$(;$W=j1Ob@`mjUcdpdHjR$%G*ozTAg^lSflL>JNF-nHm$<4uAEsq7Z ze`5ar>l-884~%FFC9`SZ^Cw4nMUy4<7{9w+O{g!KEbpmz5PHJ)DJ-nAN0|*jua`sI z%F&!=7bLJos{*z%fBYO~;dxM$;M4JyoiC-o^^XBIyR0DX0CJfi->p4VsS>K!I{EL9 zNfXLc;azM*(77AnBaoG%gVW=bfrs^qmtcR_+McdUyL-N#U#4=%Y;B=knl=ZAxa#Wd zMGbF$xNKW|iao!^F(RMZcO})xD6z6xS3P+y@GX>0eY9A#%tR?mrOw;N!);{S&oKH( z1wOO_jy)p#f&@zKD{l%ibG}`SWgn)zJkRpek)F|!MaJzeMt-=IJI}!v-c-}7gO(8U zs}wzzuy4|N&RBRaIOZO!#>Li}?4(AaRZx-M)He)QSaXAVN8@be9|u48=w-x+zzU5b zGfd6Ovmpg$4`B$zqbx}}YX_L&Xt<(@Vj-j|^0Ff!90}@9Thw-|lbE(wB`5>jjyka- zTB*g8rDk(QDT+m@u`hr9UMK!L#lVB~SIw#+Bg1W;#v9Gv?0lKu8@@SFHq0HXSzyA9d=$(c1~St zA9__keO=uXyt}vO2m_sZG{g8s$5Q9m7}PSiXJp}W^{C|H?kAEXx){VgWd5ow<3HpR z9}Zx4cvIQtc$FaAi)yIPxT0OmsT}$^=F4+1(VE|5xXefyO ziAHQjb&w$*H!67%HQKQrf%=elve4B5TBet@15*2XpX#(E zLO6wB@FKq%B>DYeTbUh->!)(s)0t)B`*mg}OjfE{*S$4&wGD9flkm(KBiNq7YRa%< zX5orm&$roEN{op^l`+P`CQ?mOdnRJyo_FeEaJ&jD$$(hF4PZ3rRaqFEE3?1rPO8_n zJg?$2m_?=XFvHV34JtB+gXn%j>qad6^HMuxqXP@6mpw zwFJ4%QRNgj9o-oh<+Ro_L=ErUZPyV`3o_nlDPV9Gaa(IQKBRK1Hxr=+-Hl(T*Wjy8^%IuEc`vGh zPR-8FA7N&X|DDkzw#*N&o}WKUnld1;2XnWkmyx`x`O;&B9(Fz& zke)iGO@F0;S-6D+rH)*w3KQ&@zc=H;U6c>EV|Q}V<@Fze2<{rF$&|7kuDKyhPXmcQ z`XUxEih;+u@`2xIitcYKP&0dLxdse?gTg9&64&PaeW1)-Nbk=UhS0~qSC?1h=UCAC z^VDnM5Kb%{l^#fLu)Q&_R_VfnN~-?WW*KM=R}!3Gv>fV=Rc>&mjT^IC@wJkS?f{U& zb(FdfgM8J}dnX2k8UrPRy$qJ*-_SNm@v7YjNXKAgzpV_7h;)Z5pr+bXig&Wk!bU1B z7xkdo_uA|Zlf3j8JZb--*-J{c!|xGvGU`tQRJrS8P7UP9Qs!*Iznm`cHeL_7???M0 zfTM)d<3z8qjz7zUu9f(ToEse07SE zk^x?8tQLUzy(fDRF)3y_!t?24i`;6KH0CRr zquG6mL|z2)Amhy)Dy1#!Q1|4PcpfPe;M4C#^+x(&PX72?t5rhfh-^3%>54j z5gnP+CRuzG|81GI{27SccQ1y$oM_Yc^CLf8jUZGXt}i{bE=KWAN7Uuw87y{{X={QK zb@3j>PgogA&Sp-_zCJY2hHlfl>dRT)ql)})Q#C)^an+X=k%=7js6_4hJ74_u9!Tc* zI{SSM;2!u|Bj4Mi6qKW%qt!BVe>x4H9ll8alL$m3HJaz;vcw!{jdgGUDvQ~J zoVa{XhK`m|BYolIs0P?)!QPSVg?7t-3|FjL{+%+p*z4+9eUko;+@$QRjCm*X9}S($ zVK90tq+~Dmn}t_hYd2zo`}Hqdn~-tNahTqZ+DWAL&`zSY0m0--R7o^(I{QF#L37&| zTfk8St|ZyMX{p68wuK-+CLR%%OBslqdhuZEnshL^o#IqRU3ib-#gI%wVXENVk);0Js z;C&-^o1yXOuSO$i6T$d5U*`O4n`^ln=VRH-%+j&u<`l{MR}b^b+FJ#b?Ax-|;-+O_ zoP*B9Bn{6iZ#>3PO3#T~10`YnWN}h6^?#U~pg!VzjPVErU&9Z+jHF9m*+(kg+aRum zvnq~99rvp%h{`Qv#4vDT0pAg|vOhaKP7O%p#?96%X@7C;6hJM`MBbdI%K#%9OSP<> zwPA15j8jXR#^4&y4_BxKTY$y-1>4rmEg;f1%H5+-9(DLiWq6{Wg(Uqr!F%EG)Ff*! zZ;cnheK9V+D%*xap&j}q?0&P0C)MY71&eGM8WbfoAAeEixSlUy7T=To9Zg{wdwU-1 z34wmK-ZAMAj@f>Fhi#1RxsYd(mp+P{A%Z372$2>pJ|OwA%`mJ)oa#NXfK=@UFD`Ye zsnYWT7^n(5D%QG_3rkw=>A0Cc?G7<@uPJ)_w?)2-9fLpzAz6L4{tfdZqtE5XihEA~M&rM%*GMIFPo`<->2j?NJyGbcI0)XefamoD zOHip$AO5dlDj)`vpd!0nIM%o&VFD_K`V4W-FI6|fR?C;e&dnk60Qei@$5~pY`N*iDEkN-N|P#c;ySFGRT&co72fx zMqTbk-4t4pfys9~y|cc;YPj^BL>1qN=uLlv>7v(~nwsiA#rBfFS_M*Ri@!-w91*d) zBOHU-t?eJ!G`8Y6k+Iv>3O`hM^sba0pQrINnZtvv=P9xmr~bRnaTE4=qs`%&7nTx5 zd*Zk$(BH1n4`@&??%;-xR6At+vwzscUscqpbzsZDb{`@5d$>8_g+?iVB|5Q1c{|lR zz}XIuw&);SDKGhp*Vwp|r(B$(+*+&J9y|gyfc|j)nK*Wfa&OWP%A-cK1hQ;#3<;TF z9?_4IdT9Do-(SD-`qv<0bL`?OWr=fA70B$|D~0_f^EUunwf0EZ{ll!v>oI|2vJRe& zh#;8mwiYkVZgp_R94z;SM7yWvXeI9`$D5$H-p7| z^lXmL2AsVRc6^chbyrqGJ{oS`YX(jFn~D`r9t6lG{s~m2B>*VA1Nd97DZkRq8c@-` zKfbKrIa~i|o<=S8w*W7Jr?o~ZF70I8Q@8;8_Jv1m!&>fMAY6YcjnW4f^o}JsbXl|w zQ6uvk8oZvDo;P`KArd3z)t8(S%Cv9F4|$REv6( z8D#J-b3uJM@PP_SAOpGz>;?0HprEGdqs)dMIR+e!`ceXJ^B*rzDhEDcAF9gHe=7HG z7nB_FPMa5QJdIl`cvnbd6I=mZx5X2YJ zOc#4`$YeEu)&8AOx|Cy5I$nwR8LfJ&=)6)VZQJ#}dQuEl@U4&D5yBuN7zN5bDCGsb zga9V?Rd0a`xRmd*)cg9|troCszfe@S)BN)yal>QGFg1O;ZFQZN#2V|XdQL`Oz#Hd#Si>Gta5IInsZD^Yu=6a5fqR7*p{MlMRXkq z0ClJmm^-5({6%hFSXTkohWy`?M6^%eohO{BbFoVv3*NJ)OG|XrvF|X6Zgq^p#;Hbf z2$d)miLY*0um4oI>YL`J(qf7M)H8G!Foh3MW1Tn4v^#G}dOd*x!ZTv(C84tCa2=WN zFD$tQRigUCA%S)AgUF6ov8U*Ot3wH<>x)4JL0uE(Lts^t7Z2 z?DGtw9_Ie!m#z+bw@9Y_n090>B8phDpeS6R`hd{^UJhCT;RZY?V(M<)4or(~B`<`}Fe z*)e-mf&z03Odg=AJpLYSzfN^3wD7}nzXaW&5J zEv7i-!cz20@iUg-7q&lNGaMU+X_=9$oetv71EBQF<=dAH)R)zHrW_-B;Kw)EDliwY| z7Y+;vDB#=Rda;r=52BKT8KpU4ArT3EvA=zM6qNnHQv%O3RPU0YE2Buv6 zR_asB#XjM_A)5v5`{C+J+1l^Y|I#2@J6EWOVu26q!kqVeWXEyB?We6)1STdJ%sj#JkD&+St^=s?p3k%42t`Mty#y&)GJXZe|74n z8qQ9@Yp&L5Q2FrS&)cC&O0MsL-9qO^%Up|zy6@mbo=*?*ltrB zKGGb><%CVG?A5JvyGP29}5wt-eaZgrDp@N z8S?u`i9CJaEOJfh@P5Zeco<2Wm`;eH8tBq{&PHJ@Rj3fZ#tM#6N$DjgLHBIN{Kp|C zfM`|TAZ$-JO5i?^9D*geI3s2M^hSkcrovl2cQ{dU9@K5akH^4{#%=}$YJyp9^~$RP z6Zxu%u0}NS>_ESDYA5KZ<^Y^z1AxvR;!F}bs!K-5WT8xYKAy@VXcLG8Ee2H%%k3A`=Aqnls6&ihgDOw(MPN-J;9aR zJPiRG-P3odpb_Dh@5*x1^X6=#%0@!ve*$Lb&8QbOvdH{0b_aex>wXE&+(TwZsT|Ub z)@rlJbL{)%HUfJ<#4vLHkU4^6rdCdv0=^&-~VId5sIq?&=dA1`t(9{kwMb*h9I zp4U>|uK_u?0dqfGfOc&ync5FH)j!ldGy8HT`L>wOwy+a#iNLaTL;0yAc2>GA0iKy7 z(BaDT%|-0HOcTCKF_%b(bmHxMf4xxn|(=nK~K6n}7BV+(&rJ?=F`y-`lv|DhfI z*T$4L72XF~l7rg}?CbX484nHp#S5R7O&G!>Lh4r*E&lag00UAzj*jPValhCa?-@f} ze+t#wTpZuVBCEU{y5thVCvP zN1+@{c~ie-8rWgwv~l2p6FRj+nF#F}^U*x{pmcpRi_MNh;QH;Ha$?QV0TM|b5lqG9 zxhhU+@!v9qK3Th_$_+8|y?_z78q=#iPHQyQ_g;N-N3O3I@1{?fe2rJyKq{vQnwwSr;3 zlHUM5aK2EdcDrQ-rlC}MN_R+KR_}7Gw;CjdVBr4X;q|8DbsBH;i>IVkoGnMtB_K;s zOs{5{ICc@ML-gh=`=(WQbUE@9^g21QpHq%#b0;4cCb0N@^i(f zLV=9S*z%dpTQ9rH1)T6$RQ5qVuOnMHE@ureslcjT6UKg^t2)X#iryEaI<2E)e}mAa z7vtzKjA!iNQ)uLI?8R6L=wa2`l*o-P*`Eh%PD0LNK{U=HUs?_e_$ z*`DW!@{Sa5lf3uYbES?&<1OfKX9VLakdLBCvRrLFm6<0iAvgv$#SSiZUo}L){vtjB zuM_jMiB@=tY{CG}uC^BW!w$bmHo%E0eHbZpQ+=mtz?WZ@O&?6dW zqi&+nTTuUgpm*#BL@)g{PfyJ>heR_}}E?%|tSPje=ALy_%2I2hDY!Vd`DUb0?pDveRjV(-hs1$9BOM8p>D# z-=ASOXKpZ^nW%X4l`>D=`mPb(1||R*+5prGpogV4Tw5`_N4x0KTk{?57aJh-7pm;k(!(e1+VWzEyYb8H3!~49zh13ul47+E2pr(Wr)90Y7P>{H zJu8Q^(fj4(-8QlHy6fHs%_fT)X z-eA4VvI0Hc!6>tq&DF6djDjlrp_%Foo=V=>wt`iWScjR*HadwOC~tDliB0=P_dosG zDVrGu_oF7PM2Q;5z_%Jj{+o*JzB(B9W9`28s0LKF_UlqW$@@V@?XO~(vvHSIcP>+I z{YcVGLBi}p(02e*FBs}E(ap3P3obE2OPHMf(?>>Xqg)y@@7u`b&;EN|lp77^*mr6; zSVyIXn|pG?`&+YXs-pXdHJ^&5cl}_rts9NVWk#Fe#)EB(Vy~XONmg2O3B5iwgsiXYsXg8$Y|HaLnw)kgF$Jha|_HdvE( zabiT(+Cf^aRTVkySEzK5o~fh6(ARU|W4#uy+K1$xj_?K-e%)~LU{j?3`Ks$(;P&1; z%{Yt)r_*gXVZC@ z{QLW?%v}(+8`lW8s@HU%TNs=wurL)GK_f*i-&*`0buCF+=jME*_a9Bg_bmPCl4-|9 z{*1ymtvRA68k_Luz!Eq0({%s5Bp;0pw&g7|Y|_lc7~O)krk8oG1bRHwkd5QuH`cr` zbmWD0jOX<`V`@7iR+GoP!5l$;WDU8rDUK4c5vUVKr~4U~W9iV5dO z`|Xf>%562DJWw@TKBzr2di(RxMebnMthkzS(~FyX?Dk{P`Fhs?v~YgThK#ghTGP&s z3GcJ!{C&mEmV|*l&4@Cok14s+|88c>e4+v1OyS#$4x*D`9|7;$O28Rm0h9J8d|8tUKF{qK3|#~l+kjj5;; zsinmMClsLl{o5;R=Z_Q`7!_rXo6^oZ2x{@t;YE`XS|O#eN2FU$t<9NdX6snN%Ne#d z$8H#d*j-kzL#bwq;{oO*X#QyIuu|WxC7^(5=FBq}lYH+zUw`ni5Zrg9+QxN!w49~D zGycy$U4gEzLD#3DLXckZfRMC#rTM2z2;0#d>NOP;*SWdZDRm*6CJwEakhnJ`>+0n4 zGgUD9)F+t#5o|u449Bb=`EV~5w1iVX7^1+d7nQ+w2ntG#n1UZ$W1E# z^ctWOL6o@6K{U|gYSdqb^_bZkArt7yHU*;W$@T3h2gZ8^S>C+5>JO03=r(y=au5mJ zb=KYw{~wJQuVI7N=Jf#82OvBuRFi*l@rL83{H4tG1BZYY}vI#=%G3$>9=nk%dy)%Agy z4!Ck#?M6BO7_Ygge)!lWyVW94U$do3kBY(cJPl9tEKNDvw|=fITv=n3&h^fST{(a4 z_UQ*S-YFZ5W4@x)+$LPHjlo85fvOEQWGu~cJh=%?s;jxXG|v1xLayOL@x#lR!G{d?4>pJN z^SRbHFV&cnP#V*+%M7hsRDQLj_`V}-wAmyeW?d}YIqOe~AvklPe3K@yx)6Q4#yk8P zAw2EkZf9#91}W}f)Eq75q*G;J_D8{Q^y=HE1#d-B6Oe1N1u6dV;>x_=u|2|H8{w9f zRRg?_)~&vA4?u{@epOU%o56HVA$(&%$C~H4zcL3gtF~f{DfSOGIeFw`%z8Lva%rbv z9{V0y8sDZb+>urBpwWL)M4!7!zx9^HPDgLu$|*~2I5 zUhHopQGYfsGi}7xswC#KQEgW;r-(H)1;~-;$|5OIji`Ah|NJ>qYl{@!Wxg|vHEW{3 zs6Hqdr(G^~G-7?PC4RTMty$*pENfmCL-;Dmlpd!euhxmbC@9_Oco1`|OR@88WJLra47CPnaq7bCl8j!UlIT)24EbM&^tjMXaQX+Sml zN$nKL`7Qb=2gbcs?ch=4ib-drQk#ZLdds{oKJhnUeJ6DMm$;{7^PXD2P=d0~x`se1 zP+mh|36ccE%Trxr%akiBAV6R0m|eNWqRV=a&7qlbbhW>AY7Yy;sDluMr0lVYuLdK7PJ_`^|@{pf0+PlV8ks?%;JYPICNl)uDUX{;&CdjWbWK zt{d&&aAfB*ams8F61ZL0I!TenX2KDN!I^r*9FxB_|9*+)OZ7=0))sFu%bn>cn(Xv8 zw%W(M7MItmjJ!bBrYLPzJG4_r4#+*8ewABFW!Pn=2^~NdaR%Jh#3jPDa&((kGTEP5 zt>?%5Vo=?Eotxm5ON`3%3wpeKpSnI``{W(C)-bXM|0o;v()SQxw$^>>#@KG%c2ixL!uq99Z7_NSWmXTME@!f)?=e2V8>f7D|~n+-^}{k zRdojC{O6Yg5XnGK@a+CcpDp+InM?)0|7ci;oO$M4XXM2n=lfi7SlYg76{E2Jak<_3 z!SYKFb%aoJf!bPUB=pkJa^l6k=8hS`v>jcv+Urb$gasZUrsvI*q6y3k=y*&}OB#T0(+&NCGv^&{7{irTEVETAy{^7>;CmH?l5cZXrQUt&yCT_FrvRx^VDUi z^!$^3UONLH<7ZT6F10cmOgLEUU3$vN(^ow(-w+yrjaZ`N3s?!b_E)76T-p8f)xxn| zFI%#znW5%M``GK2^Y$Ys)53h7NcW^`O99qq&A2UX_sv;k{uQnV4=SXhFMk}HY4;^s z6FRcUFG){`iKLGet~`*y3jkgl8T9}r6mV$u`Yuy(nh&S<;1&t9xsm$KHt74w5Gn@L zjDP)-zH%2hdxEEA6aJM#<8SQk3TL?06);V{VChgo%PFRh>z}L6+OVC?d!v|hUl~~ z(4OrjSFbH7{y8H4?Z}^+NBl2LtIj&1cDsGSjmq0My=qgPr5 zM^hjDOocEYB-S<@J@lJ2@uY%HC^vEsWLSD9(?;WS|t~NIA9~!Zt_fLp2q4xjL zOlvTV`K?2;yh}fOl*sKX+$quEhtK^~p0=ui@*J@yt6qmjcRbBeBU@5U_6=ZB33=Ln zZ)_8&NnS|_(Ee-8Z6;55AS0psk;Is962Y&ISz~zgXShw9eFe!3wx^gCBT8M)-09QC z;ja`HJn_xH_C4s4&RI$CyGFFf9eb6>p_njkmvC@4v`u?zAL`UvnF!{iE;-e`Vy_e$ zjbqsgw~MChlqF|T&AJh-q|>iKCL?w_((|v75%v(_3L`rwY9*$0s)F#6QO&AGpbEgsKX}R@!)ey zJ0E2`&y4jSA4?FfQ&v?deDXr>0u9$hs;G^y1j?5J z$l+z8{)EQ3eFwF7{U43vh-Ci~eQPrc`P!dLKhH)g0(5$T;x(#F+-y6w4F>JJFFdjY z6t4PU{kD8GMb7{-6k6(`kg;=dnUGxQ#(CXD@l)2P%ms$V;Ny)>w@znha^o_uDyQoi zu^>R=-ofRZgWFHs|5B}_+0Zx(kN(t}L6#Zw>UEbh-%sAQt(|yn)@$1~oaZoQ#loek zh#-5;^oPHst0IL2);=&GWXb9p2^nsj>CJ@GegT;ZtjK5T3Go}@4W-6`6m(HEd{d_$ zW1(0Ad0$GF|6RW9BH*N}C=_CPn1{QRjF6^lRK8Ekcf@{v8`?FHWdo(KwZ3%m=941D zxDfJVe=(Foahpi!Q!GWt8+R+=vFk6`L)+}ruiVBEnErBU$nhBIfo+To@H*sX3kr{jf&l!9vWAsG1$)$ea9s_KneFwD z`Lye6@Po107P{hLT>-4D_HbG09oR?bXwAeMN&?sLgi zk3ZC52V-vwu`K5mGOw>LIxl`dltvNpy)ZakSq{61R58ISau*C|7;A*rwTF1dSl;9QKX;gt-qq+?t$5pxZN?s9+6gRQDw|>1JT+Gy_kEy% zPX41=`(6)T)nNg!Y^75ddfhTDJla4?$rC+aa4$^%4zq4rDfYcwDNO#++8FFq={FG+ z(m%>IEmPXUf{-VVs`gU>8C4ss(zS*VVwgXj7dk}V|=1Sit(hAe6 zCApMN$qGCL0Q;=0V+OY#XfIU?7eh_XB!}^~3AT;7@F{Eq+H3?&j6dY5{736M8g%r} zsN;6{f)uI992IMHunu2-$k>EkNF7-Hd3L?CDu`8^a9Mm~uD=pR|A}@P30Wn;R&yYa z2w@$ip493?k@u)^e{jF(jzVkq@-F3e?H5ho2bB#cDBn$zY40mop9XV0Osx25cWip> zBj5_M6RVC>d9B6|i#;;6MS(C3zmZXVxe)_QziE{?g*Lw;s9fBYYL2(4hz1wPul?%v zuov3Fzi-Q5t+RZTrV>!AK$m=cB)$Gtp1|q7k%HC#iW9-k2JDnD(MHg z@_#u9?k+n!{YT;a_tKh<3h0Y=XuwmjEP2kd9eJfClNC#2x4oKz|ImF4mS&|>;!F`G zKu{T`hHhuTKAG_H6dm**Ys|_7H4rI%k4R_k5%9GIhxc4C)DsGN_6+q}X4;;ATUgw_ zG2o7U^{pv?tF82kO5&ga3l)BYQ{m>?PNlT5rGSo}TwFu?64-ixmnp6|))=Tm6X8mF znCtDCwB9=9AFr$Azjv!?c|gza#Am_o%O1TWJ$<d0Z6qQ5fh;708Q1I=e*@wlr>Rumq-_j)#>DK^Qc{d} zt90Ve+CyEYG1~X^?ho#&8S1YN=4h$(f1=Vd*L7R}Hu>wzOM67FE#q*3pn$`HB@y(l z%ud;!C(`2uMyswl$MwdD|J~<;o@>{5M(&JWaoB@X66*3rc!k-kivOblj+1{&8F|&} z7219ZpAg{2kNu=7+wUo(K|IBuPO}Q$>n;4;_yFhPH%$-*O^j-9*o@M$0BJ+J28kJK6wZ-8@>vi`=JrP9} z(1y}7>)i6s@rG+Hx|$CUX^)Q(Tb=;CdWKa8yZ5Abxp1f@Xb%dMh+R3wBqhwb@B)i7$rbr-&5pY}CN2GC{bN+CfOpQG zmfD|+f6Tq+8|qe$6_F_cs>ClH6$dYB-M z_;TkU)~ZQTdP9~IgiKw^5yfL>RXMgWxA>~jOFB%&D}!||#y%>qg+6YB zr>$zogFCk00eFk*7fa9xRW=k% zns%Jh2+LY8fTa-cp7TA`5oB%`it}!&mpc97{c&FQ=q56Sn;mEeW7Qylh=t>R{N9dJ ze(kSEg!@{lHz0=qx>G=R2byH*Umm1K^vThvJLFk9IGZz67K*>kG%~6|_lOn44_g0^ zh9o@ocIjd!oD=?#U7}+w=#9^h>$8oYJ~VH?-owZqM{da^xcV&(YN3b%U_moiDx5j-zKHg&Ph}J-od}?j#*{F)#>3 z35a4l9*6(t=%iO=Cixtkxk|_`s{a<9A9{WJ*UWfb3_a{@2MI3}Kw6H!0l zB!Dwfe4tMoK#{9a>bkd1H7Cy>5J z3^Q%{^s6CrGjcL_8hkW6eq+Gvow}Q*T+T;zxqP+k{BTnnuw#ciWsj7K7(6fcKhFY( z@kzfK;d-T)|!v+0std+Hbe!IO5 zo%fxfTw_1!OSEr+c%7$>idijC$JhdRxofoZjVq;e&#V8zP!D5o5|-}oqDK!^YR=Rr-SJM@VLP}rdyURwlfV~5BnZ@TD5#if3US7BCO{C zKW4>3Urs3l$s!<&H(1D1cMA&@Jlm77MklyM;e$CvJ6LY8=6hO${jeECyO1HWXEd6LcYUTsQh4452HfY*cmkD{|+Xo6kCFp7#wi*yX7lu{a`M5IJQrBfU|Mo5ho zq&p-e21vsO5~I73&e1WtH)4$1cXoaP1KvGxKi4&<*@yj$c@-(TaOkZ?Igq~_zhw0B zuh*dH#ImA8@#=Sak-MrRLZ&kr*N@cv@*(e(kpk;&GtD+Gt687vf)ff&-a7;2yBWPI z>bhn=@C<1RRR6k-B|KI8qjO2UOx?r42Q7afKQ&Sb*No}Paf4*L&-+7EdH4FISighL zh_MEQY7vt%3yJzNaiFhkN`X4-D%_t`FMXBL?q$uoaXP@UyKho)Ap8H28oI7SYhk|| z`T)~B?-}7MFBefX0CIJ)XDDuHRn1SJx@lTxWZdwbCg@lLtOw*R+u|B~Q&*+UDHp^u z?gWb6$$wrj<(N~)>#V@+dTam`(gD)*W-xz_hK8T4#4SIWyrD#Ayql@nXXVDT+VRv= z+oumV3j>YsUVFa7)}tkyRZyuOO7$_NJ7b{(`sJ z%`UDsYj6^csb)U+d=tVF+(@7~*G7W$xsZ8tkv(B7<1CpeX3$`9=*00MAsrWIh8r&y zl}9^;bzE{hHWK)xqSbo8r{^nv0Z^k6*YRp0NoD#K`?YdX!0Ijc%ePMF_uUYA3l=yh1S{qDzF)ITs2VpJ%v>a9-}GoAp0MCq75 z-(zOw%KdnxpJvexGj&yK4t&-)Etosmd`4O;ST4Q2+&Bs#b}#AUTCQZakoO_8@K^&`_tj4wYtzqLK0Y`& z_+UNb0>qi^(MXzQZh+x;Rsj`s0a?aRIe%_)y5H=lVgO;>OqvUahIM@Z5%rbI2}R@O zL$u3vXZXQq^#fA~4%gT5@d>Y2nYt>~RnP6X5fhFT_aZ`UNbIwL6OGb@)goP@@q*ES zi}d4BBhO5mOY_5GZv%%S7z0&t~5r5jGVp|Ua zq2c5hA!V6p+i@~|B0>neL8mKGZDiuv4d>**?_H3qBY4b&T}`UM*es-X#eGcC_Hx(+UTH&wFCihM z^9I~X75UZ~*>3k1(?_D59&^=Z$xJ9OtXto&KEIl3+zxk#e||vvwbo@-h+*L`rFU7P z!aeVd#oqVg-bNS@w}Qzf&tW`^u>u5Zef9;Y<3Vw4~@*qg%mU^9VYnq=$(o0ldP zjREIn*cMKUNk<4Woa7DwV&#+Rm{PJGkpjTN41!=o0vPuh^hr>(MeY&&&<)#|>{|8q zHz%c{HsPCLsbxDQ-AKvFIpb~o;io;jML{*N3mil@zGBp6^DUa}Yw1S96yf)0R0^e= zd_G=YI3-w+zRMg;88Z5}PqZ#wKIueH9Cs(1gYaG&eM+sJ3x8w?by zaQ+<@fXT}_ud^A-CCB(V742UA8+CEL%@rX7N9FJ=%mkVwnN&|6oclk5g(b>Wk4p%yjHAp0C9(8SC z?7aF+qn(x&ADY1F@fYM-TNytiE>sTmw3w{GSr_j&T4%5AT1I`IDibbqJVT;eZwMTkj$`;(R${%hW{Cw)QajvH$L24=})PF<{JN8;^ri%Z=S) za0P|77v9jsR(1?QE9L#oaCxD}zqIzd2sk3}-9s`3&dh{Z7acr+=cf!Y{am?>gcnMx z!YbN?;Yi^=v&Z-kuV+XeS;_Mf!26kev~CMB=icveWjwf%u6HYJfioU)&d%9DnHJyvA8im!3d%{9yO zh6~R>Rw4SJa?DNsq48dd1G0Lg)4e%V{P`1_7#N)jZv6k^f+Q|>g}Qpnt=QP>#Km^KAqklmI5EEgHBqy-p?&QlCpFb8l!Ha9fY(Z+iNA5 zVBTA~US*J<9~(eXK4qk-^%|cR=?p&d5CZxk%R=!knUT&O4?Lj4TK932CKERb;s}>A zdvj~hz_;75KU5Gbn#bd@AUccSMJBG z`>p&4OiBYtASSwaJ}cAZ;ZbJt_8?2(bBTA~Rb}~%7e~jMxWZyy)sSY$Q=8f1X`)r* zdo1jAk6&>N-1+=5x$o`6jp#2t=(f=F3SuMsBuM07cRbDWmf$*T^+8ug0K0ihkm`uY zq#UA42Fg6sTwQE$_F}qb*2CP3>;8|OP_`OF@3Pz%@n0@ z*KW{>*odoGxjiB9`Z|ncqG^SC_lvI*y0NQZ=V~UYVty&NnVyd&Ua9_MaC6gm>Sy{0 z0w+|)xzF9OUM8!km99WmX`r|ReQ?uYXomLMX|_4yiK0jFX}p~g3mIXS7MwY8djO;A+TI;W}% zM%iWB_E#DQG3sPj{_)w8zF~%1GXG7k0KUL?eV{6wCG6hm0Aaaxfp>p%o?Aovy zQC}a+s-hpcXn?cPtf`W-RlF#8xvaeEC`&{{fjHAY^dtavJ-cs7yWR-q*D~pd?;+o0 zHN<=A%b=dOv)m&RxwG)o9DpCdQ)q?bg)v1@jsnw&7w!)a&!Y0W<*j3~#Jdg*g;n08j@oofk* zdFKk6&@58yGwF==SJ_dU+P``=GR#?$v{3Gv>2bI9(`}s`*)WC}TZ#)qksIMp`jCcJuzQ;diS-0u1I|>BSjO4zgA0d$fEg(R|}4REMUu~2n(_BD;SgoZI&xG zU7i=fS}|{Qk2x|#;i67Bun+D-e?wE$F7QVkrCzoPVmMcct{ngX?Hr>WEdF%ea0K@*B z$)Ea20<^<|z)zES*KnJRP(PbEAb5MMTU&jI#(jr~@2Rl%{fk_@uqFsyKGCR^n}JE3 z(*HeVJHK+roc7h$0v-|YyGdFIJAOv9<^EuUO180wJFZg+i|IEg3}?EV5x+GxS8tvW zXDMZZnyk8qSmbj5!6=_1Nl>u8tX|5QEDx6dHpQ(X_Gh<1fQWjrU2Uhjv}&e5=7+U( z*f@kZNw3XnG+2)Rwxrn#l^ukqrGFEfhuV%skv@B)9Cq;CE29naE~YGAiX?q6U^R)< zuYf?<>W*%;^ehGAM><6~2uPmh%b;^kih$lmKm?#lCtan7ujNaZetK_5uMnq0mcF&5oddf(T345!l=>K>euEy1ad2b?}mXOW07!26WoCb8VBhgk)P-p zb)P72$^lo%iiq@o;70?RZu5PmQ!eShFb=f0j~d+)P1S(u+gI-VnQ()wRmZBP^=Awu zuKmk8p-H+3AGi>^+-<|t9#wFcI7utPj7BE9*oID_lw&UXwD356Rrz9Fn@PQ)+1A0i7Typwhjkvp zvl)!{p8QAT6xEUqjBe@&&n&srzm8D_X6lO&`g9%KAj&B&yY@i|s)CL?+rdzK2HUGTa-^(pQL6?vaNzH`==0j; zZQ9yQ@omLD*_wKyZm!}dwr7hUzjE)3kQ2B69Go!C?YF5ylw@XF+CCGcy5bBOd3bSb zR7PGvFoc8d(Hb z_=;cGCKA8{dTZg#87$Bi5>8}+3h;!b1CKW=+TppOQp7T$37F~VloLpuO1vSd?K#82 zcm%ymP*=qTgt20YuWin}y|GE<&rTz_Fv_Y(nYAa=Qq-Yub0I0P-O*V~?9v=v*CmfW zQh(@n`{c?4qgO&*9cuXaD2O_+QrZ8rdHLE6`<*|bMS1ywC| z_vBMwg?!WJsAs59PU@m#S_vUwtT?L;9IT^k=GqrF<93t?ZXoJS*P*KU`Ztafi4(Vz zTIR;a{b#~ApSw^ThGhi=HlD8__EYZSroz4fn`pYE%u7$sAv&>`s1(^svo%Z^*0v4p zP;FvYN40FQ&RdmL#eN7~iSa6IxfWjXeLFE+*yK{IXgvY5UeQbdN)Tb~9&!>VTqwJw z8ds3c#gj+1YoN>1~0?-WyD2;7IxC?wc6!@x7LR2{~a=3^*pub^3 zz}3)6oouY=+5#6cP>JD(d54GUUPq3BDO%;z+G>4|^Cnse|FuCMeIYo{>sL396E|Ax zw(h(13cnEm!5OOVLz5y_WwjA4gik$WFzp1S#_6rnZXS#WU;r^PUT7$)?-0t2)3raC zhcwbn;@XTTo}F5MS2$T8{1xpic~QQNjkyiGp5T6{UUi`@U~+OMdGWv3NmDY%14Mus`RFpcqwP<@2!kdNLK4^u)<^ z%@&XG4zJ?HVPF!6@{#e7|J*=DQIW#Q@^&h3DOTHEtA{-5yhDa<7aQP&STh??YLqAR7Pg~JpnUmD99|$ zp2Rlo$@HQ?vE~GLA?fEC77*gcgYxNao^TZP`@n7B^gW8->b)IDgLOPK48Xg+AhrgT zLFX^uM;dD-`x_V>q{vkL6Y3Z}uh`LgP~FU5b!krQL z^NF+J3%+2{0FLKzLK$dQtpe9te~Nm{X!x^fM3gx$b-tuNRO&6?OTBp^!V2x4%OcaY zJeA0SplOmGcEV&bDjGOl3$L^CY2(;}0C>9BMT|7leg7u@%6^~Jwv1J&z_(ZJt=vP9 zf`RHFV-3arIk4=MMFKZ35j&K&GAU`I;TR{VblY2i-tH3Lg_}UqEnCwS=ukzK)5_`m(Mz`K4<>8}bLX=jKRz<}If<5z&LA^{yH zGAf1H#1Id2ihs3O50@IMe4*q=n+zO+%9^B2LReH=jPSXAcECo!XB6x79EK#Aa21x# zu;=9N&KBm$)tc>qL_XnWP<$MnDsy(XHR(32`O&&l_IAM(`@rAhDvdj;6`#7Ko!ug;0$Mk?`=go;wNS^Zi8Ct-kI!bas9D58eV<}Zxu>kubf zt&ln|iv^j$ma;PmJSqLPAw+&%ceIlf@EBL7HI<<>b!Z`8E5T-ya*wkn%;{@8WpB%4 zcit~>+KHWYIK#ip7P4%56POu$YyG^;?>U(t$Mt=PcR{i(WsyI7>j0FZ(!-xSd>1kv z-+WOtu$Kz_IFl zxCJV-dWf{YQ-#qDftA=h*|AlFaR&}F42w6F?X|A&SK>aTW!^)dt?(DnB^}InY}xZEc3ukc3>ecvvWMr$zZT94_2d#+R=vDqClbbUGqiPz?{3lAsU&3_vYK6dtV*&P)l z9DTBCtY^KGdiC3(CPV7Z3b%x+8gWt1{=WHJdnV1)HTf_miiV9 z=ydbI_}kvuAKD_>X|af#y=;33x!1}2=pS|SsZjP|)}+L95c9`eO9&jws1$r=lM zbxch4(zR49>*~~3w76Wi062c~VC|bXll*5(?=-&8NJrfJ5(MXrboQibd2>Z0veAavG+eot{QkG? zgXFd2*zBkBRxQj*=qG)^wFOiAU3j_wOzp9!Na=4X%b>Nlqr|bGxLY`$%vZ-w=5;G) z8(}LmgEVMJ993-~u%Tz+Z-B!gZwDy%-e8Q)D?M+XS_jNEt!c)rHN}zbHX?60u0lp~ zi$-5M2@^YKSh7&PaqCC55U)8MR_5L4<4)0lt}C;j`4Fv-=+T%FxHM-pP~c6n$G1Kr zm(iKl^v}O^$2SUpudUoU5PLO8iH$-#MG|rnOFk-NW9sa7a3&5xTo%2ZMgO9+%MR#( zRsBoo!kSa4+mEUqu13?L!B^~$xIX9m+_V{;#Sy~K-2smYYDWD|X+JTT7^x{YA6Rhr z*>BcdcdZN$N}}3zXeN>z!>1i)roo~836LbRI8?ywnJzPyV^g^N=$;QUE)&Iaa;fwm zk!S#Ry@{^~zrg6FekKVlxNXvIM(8aFoc|hoPCOL7qpR#qmh>~*XcQNMk-~FAI6D3# z^1*Ya-%p7gJH5_xh+%g2X2HT4*<&^ArN)OWw3sto?<#xyf%weOb@K>NRGIi=WJTlF zY<%Tq{^@hJxjltFFI4Mf2b9s;Es)91?1B(t2;g%Jcx5#wC`}(>VDvP9 z+s9~B%WP)fFM9M5L=P0lv}8|LxoF}S9p)M0TB!*1_wnrmnCR!=$MG-2x>u^%O3R8@ z7VZ5%{<#!178W_}Yg{EBRZQP$WwJGr2_QX+O?QO(8rnNLI^K)44Es{2K%;cG82{{f zwJTEo!v;%-;S9(CR{5PN0e4+-2Wh=NNL40Y{92!O5O{_Uo zT@|0qGYGH_EyAgA&&8oTM&L%eB*1Bh&$CFywctYv0d%0wIq;abCe1W|;G){xAHs+A zX}tY)J{U)gD?RPSvrnGgJ~8FqS67#I5mtG*F8p$_Nws~u02mwdsHfyWmkm7bvwjiF ziI(q5TSbZu(<{X3C#rt66TSW|XN##{wFI-Hy{W$Qt*^udP&Whq;76Bb5!D!vq;i5% z%k<5?x@trU?I(v*5vf=ETNES(eioRnUVW$-j_1z~-YLpgs%Qtyl_b2YEj-}R&TsE2 zB+nbuFrxLv{4stq`|oj>KdUblh9pWx9<>De)I4@{&^m49W5eQ-<`|u8YWQeF6w=q? zYE|?47gCUIg~!!sGOL1P$0;1oTbYU{U&gsV^`ugFxo!KN_`Y01dD(A7fmMMht{pi^ z$lU+mY&<%@w)p2y!NArFiiTEHV8iY$oXQmrr~I$<4&wgSb3)cLoX zPzzg=%a_ks>dk&Yw_1m8oBYK=gs#o$P-B&n3g>ZoAjW4-Wcz|kt8vc__eif#+mEji z&KABE;t2dh_-iQuc^VbcJ5eH zx`}l+ihqP|G@J7DTI08mF$#+nhjZ~ zQlv$%s-vg3tBGVxY^3q*^mw`ZE6QCtW4kgkmwxeTvb9E}DT+A?5j%l8Hc+=Ke|GPZ z9Qts_<)%!eYnjfzhUgg(vs_VN|Y$P)VZQ6D1@kd9LEX@N*4~-1<;yS#d6DJr97;)%A=iHiC7z#CJZlg0od?Xn=Yiun?Kl zJtM3_%ym?9-JRsx3r8r(C98a55=?r28#{Ayg4z=Zu4b`8P6U6_(n(UQMX2Qk8J946 z@U{(SyO`WK6T+)YtT{gqa2DJvO{N+@?Gtuf76r3e$eA6;*>|BEx}X?lok@WsHVq~4 zTD((yg_=C^dC?P1kAO$^`t(Hh^ZCwwQj0@z?dvUo*>nv=xUsZ!*)H6Y?9~13Yp-Dg ztpigL^}71{bkJNK>OGI-gYpFsJ(7UX*sTTK&l)nuurDN^1G0!-7!T_$gCJ+K@Xt#B zo9 zK6=lWI_~FFI)S*R_ST2&82$qPBSMy?re2w2JH=C-xXbDu%XD-2d=e;cDdkLY?QqKP z?f$1Ixaiu;8$V3C(P|v>ODr^zQ)94x`|KRXT>o|I;9?o{SxuBe`RNZSnf3WBA7D|K zZu2zvRDO71m7E%20-jUX(vnU%dplL<+>!akt8VEj>L46UHE*={IlyKP-Yu;BM2h=p z`A>l8_5b&B{*Y;+}TCM539ad~*^>@xGCSKZ}0tLXq8xB3C^bQrP*< zi0kouO}Vd9i9kzc3KQ>q`@;y!WI25xUPFJz4eqIH7c)~}^9@PjTNzkGb1SXQ9eoS@ z(o`KJ>4bPOPny)I#d%_1pQM(gnl5c@9P`fI_lUiA`dm!fz@RHvQPjv6d7=H6TN#MB z297pQhxxJagNJnt2p1!@d z_ESjv8O)X8yr<#XHg_5@CTPFZGE;FZx?@=xwA@R3yCA-lPw6`iI4}j_15)wVVyfFN zQ}|#9f-&@q*mP?yiq!NQfTX_=@{EtX1y#tR^8Cdh#hbs99E|1UqFQ0Ck1;7x;&E$| z&H6wXWsTM&a{d_`S4#dT%2NX)lxDJg=4)}?gdLeUmiZ9SRk!@SxvI`RL4bP6iQ`xH z>#P;ghW;+MOBJ{xCeD27hA$_nXqU+`q|nIZxsuz&C6ey)*)KXgb!^UAk0*)1Tmz~D z#Yz}-S*>M1BqTNw(aOxaEp>{n_Ug~l{%*RQ(tX^BX|Z34adKa|fAgiS3PT?U16o(} zmbhBRkPlHj(%#9xpHTJTw3i$R$?ltx5bxD+MR`FDcTCSc1K zZS2;?qRMR9?xR~an|A$KkT(jRoG8_biVX)75A8*2sJFBKFVd;9HCeun*2k@t(`|px z1-@M^Z#Iu1VFyB)$?P{_Bt>k9T{Bj~!D|4i(K6&!hn^hkRIX*vmaN*6V|fxMEIxBB zP0*8Kk?lL^CmS_JZ2EQ@b^;0Lq5;h$n%Zz}yv;|^cFc3ig+YUAS{ZRR8kibyzl+FL zPJ1Jdk^v2C=%7Pyo`+VD@PVa5v`F5vvmvGydg6#hHxYOw}rSs}v!x^hwdhEuUPD&rMn zgTS^v^$JdK(xt;3SJRhBYmiVcwT5|9RgoFeS9-}&&q_Y zp)d_*gsy3&(XgJ`Rzz==6q}eX-$MQLFdO95obfD4nJn(BNKZH<2_^qSj+r#W1APl` z&31nw{w6t6-Gz)yAtFAhiKP;|4h0c+`Lkk&H#epT*U2W+0!O-=ZC>K-CoeWsVGm|?fE8@#Fss}L<-c=>Ezr}bnP%IW zFTw*t&`!T<&2CF&{e-{;B7pa{9AFt|^8wA8>CtFb;#an4dbzdbQ^Hx7xsf8+)-(Fi zXJ!?{KfJa-tk|^-K;H~I6*H@Si%{=u=(Xy{6GNrS<-5~sb4wtFV6pQZ(I{B~g1FqC zelSr=x{++PTHHh%R#t~CkvFmxGK9etGVKIj8@VwiFJrgLQRQ4x@K1NMHW z&%T$jI`Pguw3pZgWse{4QJ-q)Nhhm>I>ajxIofaLeKaC<7&wa@Xq6$9ueOE+=upg7 z8QlIVxize0k#yluTBX)&BfjDO-`V-6NmJfPv6llnE-sS|<1dOx7jeh!D^=TZZH~vx zxS!orP3DFQ!YzmAgJ~8mzhh;B9looQ1dctvR$L9cd2*$7&(??%dyCD;yS%Vfg8t6W zAD8Y`AbsY~NpxBh&ElGnU~UMZ=}Hgi6u1j`fOG1i$F@ES6+JmfzB^PUVMx5b)%!q8 zOg8klc=Fnz=BNhd{?A24XU<^rw%?o_GKmnP4dnNP5fr4TS8LYQ3|AB&>d%X5MY!k9 zR}FpUvxS4d#V3*+{UK%G^zo?R!5yQb%x8<%7T*}moGpF67<4*-OXH~rjRzd{B?Uxb z!KHEE{mKXn*>EQJkgQCgSzVGzLw%sBxdv1@aE0Ybb9A<2^5zONo@m)O0Da&ONJn;g zn-!FCew(;mI~5e|Uk49GDvSVdp&}**d&zmE<8dMf?q8S0N(BPFwSwFIC0 zP(@SVTQvF3h*t?U|No`kD`D<_j22*Zy=hhfrYn$5EQZEbN}FhoZ9Nd$z{uS~*_)t2 zIP0*nZPW~5ZH)ur6Hnd`u)oV8YamI=-1t^R5|XJeYjZ4@MU9N^^D+Mpcsz>(u4NzG zU)Lh-9J31`UmbUUnZVuDGAVe2%hGzxZ5xf-z*{-)A>>2kTOQIOEy70ots7Y^l8*xi%dShafZ|39!?!wV+sZY?HC1E!8Fg>k;n2!t9)d`?K$tu~*UhK{o9B8nR$P|zkcpRNCBO5S;1Ho5)Y%FNX zLs^s`j|RFmFLxB?D~6Hz!Zj6bwn55h^-iI;o$k5Fin}i%(r~XTY_%mU`bG&A5Zg+O zY<6GElIwj|WVoBEanHr1fk!z0pMeA51(_7#rCC5L8 z>n3+Lg*XLWSD?J5dWrTzrg#;&R_Mz?(G+@J4Xz4(t3_NkHkfdS?`w=H>vn|z6apUO z#0mC_ni$qCyY$Y*>=faR&G3C3@`0P0ATWu@(VFP1jo3KkWSR??>#ggXw$5MnbIc~E zqFml$be35QV~4;vbq{b)%Djn9oZU4uG>!pEu_sI^UH#qd6Vo}mc;jkRgHG6RT8fR@ z@U2G6;~$M;6tPLu+^u6W67IJ#q`d0I8sWJbb30mu*Zt0jWW{8~>?u}oO5QS?RLupv znqhc+){nY-q(*Dz^W(cg3L`tFow$&1&ne8PFblL!Dl4yq&aCzD)aIR4d}zSYc@?+T zdmn6HR*tJyMRH6D9*9c&=+nOtbetvyOG?Uj&+goJSJvcHJmvqGY!vG^nrexoStln& zePrXtSZ9k~e5qTQ9rSs!@kDhV5W+b6pqX$7DHj9xbwn06w@mOPX&`K3pW59qv5|+6 z(VWqqd&b_#uC-_>2VH;mi8@blkNIZEq-G_*^l5kT*1n^@KDDd*qc5L}e=i-AFWq2B z9nq@eg&e}M83trhcin0GXyaotido(6+BT{ZpuQ#uwH@wMPO#Xy7(>0UKU6OXs zpZvC>SsG4f8OLnd8omom~t}5F2HEMm^3Xx z(GP)|1e*5Ttxnot!F~Sf#WyZ z@OM0)nc3>4)+^RN;=X`Es5W8+m*U&>m)zHtj89ohong*Cf$6xrDE$7Xqz{P7$@RMG zdVkBb+D|ScUN<0cvjTi?`B|#Un3LRK{x1JLBt?&r9><@bv#ybGphe%7xN`hUTW`$- zPY$m^Ctym7VbZVYJNpD@P=$#lpsp{_pJuKw!=`9u$z*8Ry`#F0KgY&);9QpI3i)HV zjcOjXpgnnv*hOYIT3Wg;U;FK{bJG%%1_Y6kppG)sk$8gR%vmT_Hj*ZfX$%is{xN? zlvl`Fd2iG(Ci3K(WhBu8_)!}t0>Nb#^{G~DM5zCQH%hF`=CVSLL0)zFCLi4$M<5n6;Y`7x#2MPFX`6alQ2@mfGDnQe=E#AH8RxbCv!3 zyZ^sd{uEGeSeJKTe5D5|@mCw3LP=tTwZy>!%Hmn92Hm-3^odOMh-}$;%b8uxN@(c5 z_7vD6^hEbGKa5m#|F%cAdjC*Q6cFZ5J$~S>p?t*L@8q;`{XRiB<;0?wBU*^XMoMlNow}nnvqJ@b*BcZ&N()Ly(?+o zTE2Ap-=AvMEgFT)V7(zovd>bSP9aoBcNDI3F3wRk4!(ER7Qh6#CKxo3_?0U~{X4VM zcM^te;**k+s4OoYBk*PIQk!-x>leKuW^WeHV6*jhBddSIkh+94%c}ZV+ncWI5rg8L z{I6fnY1db3ctUCj=zzKo5L~hbJ(6MNCAL9H{P7~XiOePBQ?G&N5lMlM5J%a&_=X9D)CvG&X zG)A(Z(Kp-Zi$FOhTfpDj^A>De838EpDlUOHY*zbkug`tr(~74*+mXnL%NQHaw&^^M zEB(E;2st8%Q;%m|V^+^JOdS5EGX=Yo$1f|?C&^v@e`hLljxAHZxEvvSR&2ug&Y~g6 z(*YQ}h|E=&`6c@4M)Q$XRepKuVH2`RxMJ3AY&Ij~LpR1F#o1 z$|u;8lZ|4{9QMWc(Zq2%4A?w&X8h0)^Gp@#TFG*H02y|H^5FQ^Sed)N+to&pALW7| zj%)@TBX@Qh&S>*Sx9|hn|K>d%5Ge9D>)rmZXA13PDxYoK>3i#aQG9g6Tq>BsDNY5$ zAQ~e)Bo}{gyRbI8mG3!G?p!IS=4m|0aP{M;OO-oO-fEW*vB0ggzX=Nx%Ya)s3LF9( z%_R<$E?$KH5NGrGsz1_2$rP*kd2=7Bzo59o5&rAR2ML*#f!4~fq3iqI9^xx}{r?Q_ z5NA6~sof8m64vknBs1tS+G6T{DBQZ5Zb#~gp{?L;*grM&NtcPn#r^sgV}ME8`xl+2 zHoc9%QY!oZ_IWxkGPiZcD{8%SC;9=f9}m_%^U8q^uZd)yj`)|!t>`Dq596gcg|O~ZOrJ#%6G^F5%vPRxYL0_ z`*D*0{rnR%SmY*#XhuIwtgR1~Y;-pXfnR#~v=FXe9E)|+d6c;HY9+hYN< zzNpyF5!m9N1AibZ1xg&;luDfG`Da1B`ERmy^dMRILPF}Zz>3Li693^=(ke_8d^p;> z#v{M%J=HgD$i1(+ONv-8w3~N+${6nBJJ=p=0kaBELxuY7x0qJS?o&eIv-CeAVL67| zUo}4R5di>ERzR=*gm_pnCtBLXgh5Y=?A2zaA)!;kUI|pjo^MH79Crctn}v!XhUrTP z=`N5AC=*~y$$-p_jZBYYvk+7q@$5i(myHc;Z<=7dC>!Xe;N;05W&^tM0f0>Sb*&y~}&hrQovYDOXJgc9eczbT%D*HX) zac7bS6mL~GyMkfY^U{sqew>?VOhLS{rpQs)l3kq`lP8e^F%Zg|5?P7(D zdY`t%p$6m2?9A*+ z{pe>neL@g~w405+vA%A?ElY!|KJ)JI-FSU}**ol*U30w~P2A`zfEm($I|w6mHZ)40*Jx~Z!NOlFFNReuip+lr8&7xm<+oa)_0$G_uT<1-~H&WY2^+BY@;XvDU&7w_Rg6K}f^#5V<`4}0`Yb_9z+nf?dV1=brDo+YVac{GO zpAjJ9q-ON1Z9k!m=)Q2+xfVIj{$wdHxR0azkUkBLgbGUz+wS>4M2h*O7#wp>JQH?$ zh;%g6AKO5(@d*`#7q0Q;-%>P6N_E(~nKS!-b8q{3RhU}1)5?)}0=e56rk>&9SA{r9 z?L8zm7$eLxwIXTk-^i8NIK3SE6RSQbQAhs-hE$q*01&@J68pR2kIbjFPiuakd-5?M z=RKKiqLqE$4RQ`+?VtkVXXdPSgrRU)86uJ}t544}P zn~I6+7cjfy!+~giCuZ3@4yBMruB_CK9vGsW=JUGQ?qgJf&$UPvcQpu)!D3k<6sSH&w3(BT2IU0vT*0P{7s(n{$n{Da(*W}UTLxL4?lP9v{Sfb^$^h}X}< z@%xLIi5BnQH=JitGFM(2s*aPtT@D5Lae@9$DdvnjWGZEeS8!iS_FpTNkg^*-~ek<|5yhcFK&mK4%5N?yJ^ z?$tOX-`NEW5VZ1F_M)SOqlZ3qekRWS^m5nk#mQVIkx-M2rFSf%&zSXbdUazgo3>1> z4&nZ7@$lK4b5|{)%N9IQA1_p{%oA4O5LTZ1`uprA?860N6G}87{+o8n+eG4}w3jh^ zrgWZ9ObeglM;vqMp0^uPeXS&AW++bDZLo>B#EdU#LBajarB;SYME-;v56+{fJa6)# zBDaCQ@H4IX1t(GW^*W})gy2BFmgQL$jB+V9DKk{#j|4}3Egt13IzNY3Q2TdY1%wms zT0Kn&^pC=xf&;t6B^r>VOlkEKm5m23ru1QMha?>mZ+bI8MW$vSi|8T~QeyP4yCS!` zzdfx{U;;~5sgoIBCD{H~uNfBf_W?(WG`?Cd%fcAZxLlXK&!L*DR$ zAA=RIl}B~Mlxrf^<6x73{G1iuyJj9m9pFB!x_i_zC$=r?@mtr?KLIw7R`r;>OO~WWT=cKRAgDj7f`%^Q1c#HhM{1e1}^$0gTQPRYB+TzmR1Ps>y2@MFYF7OK6R+Vz8g zQKJcD!BqalRxDD(SW-Zh9m-N+L3p1Y^FMe|3%2Hqa<4>G*F~qklK9t-ElvORMQKBH zzV0_Mc{Dq~#f5-iUV9pP1+knG%LUAHoH7CfGAR}36aTFfT=A0!SP6ZalzEe&E*mMi zOw2n)_R1(#L`{ZOO{$}KTCeA2*rHxYVF7HoScSYi1N05~Lf`ivx&9jAYgw|pB zk?1u8|IDuPBzvzs#WWkD;NM@u!A&XAziZ$6>@5@bQqEDrqp(>`Du6G+M!3fDik#ko z`u|e0$t~!=z7IT%SycGD=gQ{wqikaN%Q$kt3u0CNA z$?!c$ZQ+69zE+w&-HD-JlzN<&A;rWA`q525*5{dKd9fxF<2|M`AO)8Js)I~*`=msl zE;M=Oe*qUW=*+8mXJpaq8lZ*cK5|7Df1vc|tz+umD73eh-s0BA<4}-r?<*Gb57Mq$ z-f3!W?R4!nT~hg?+GUg+4{%N@3(IX{+e^5Kt~C2KfxN<1*UUWh^!zD`<#wA?*AnW> z&9~9*nM26CcI@`eVP5HaeX7UiYJYDk_;rsZfb^{k?ORT?<{O zTcM*|MQfz3s_!l4u=}IZnGA~h+83Y8vC%|<)8%`FI6mX@%~HI5QqsmWX0)+|TVoVn zSJ>6vPWtBl(i_W-N(eT9fmMJb@cb*6)_g;z+$_m7_j-XN3%7*^s=;xy+1f{MI?a7F z%&bbrhXDK5X6+mPef1Cf`%a%)w^Ge(V&Y(-S9!@9_N?FS>)-C&f8P`nb=3Zlz7_bB z#F{UN>@O_td^g~IF4om-;J>_hAS<%YFqvUG~XZ4#sOk7zC=`GNUZXQmD+IArkEzl!x;KEuGewc@jfith5= zpqR)o$>uBJ#AiP@Kb>@zKM=e_92eSti=ydw7Z$Un&Ay|k#kHYbn}#;v`J4a&9FbMc zgstMeds*=ZjE0?ksznmo%WNatAyP9ND`y`m;|GFHbDjv<>WP)dc+6agA@)jkHuI}9-x;8Y5wS315O~$f9zf!KMuHEmMXHA!vmE#ZzY?A&0HkhylxVoo!WT11mu zQqp`Ycc}QIONYdlNojZyWRB8rv)ft88xZV;awJ@w6Y0%Ep?G7%y3PEBd?$V5i?p?o zB$Xy;~Gi!E7UFk`=_mQ+FM!Jc!uKF!#)|+g}l+3 zEv~g3`S$J)J5{(D>S#c1P2&w)#3oHew5g_TI#o+(FEo=5;k5qqc^kL`fsAukyf^U! zTKJRU9ZBIfz87SSM{Z^zWw=$(n8dLPI}SKBYJc#SOW_o~xbX$9iqf*e+r~t}!B%bU z@~BhS*w-hZ_+P;~fLk4VUyknmZ5^VW8_mh*=Ri9GI*~<+OzM1T;(rdgGAHyZ}>ynIU|lcL#RTEjLvu-V9xG9HKSu`ap6A}>H4;*s$1y#P4c;% z8N;>IAbh+rAu;GW)gnugNqOO~3Jbk1Yd;9-@yoh-?;vZL3obzj*b1soBRS7KF<82d zkAdUXG~Gj8@r0K8rMrElVzZHvWDV0Qfa5sH_p5#$@tika7qR}_*DUX$Xr-1LTb3DH zR3{EV;C16UCl$-+UOLnDOIhRauZ7=Gj#-Py(ncd@jB*>McKRA@X!SdP73jVwwOc(0 z!`GHGYK0N*^?48Pqaf~@Nq>Y450|MVRz0VK^?MC3SzR{r&d$y#%r0k{WAo%c^Urb1 z1IJ#KivBL~Hm$Q=pHzdxx?31+?KHc%)tYn8c4TF+GEFwq#BunK#J763rw*m!3G5?L zZ)ld@S$1!f9i3UfKm{Ir10dQX}8;W;&%@RnYZ|H!C{`ctnUTKb*Eo7t(}azUDTQTcAdQasH2OEYKi%_WuA9gUAOWm~|g>scT+0(d_kT;g3bOg^ZUo zKl-&&IW(YgN_ttyfvof3dtg+I*K$33VARR7T5? z2t@?vZapbUXm@4!>0vPu#6exf-&5e<+9URC)qHE?8TED2yg{SG9HDJ*(!rxp5NzB@ zTy7Y_AcAx2S2bIB?K}-o7S{e*A|_UmhJJ1bIQ*;b4PMge^xKGaZxBOc4ZYsW zM73uB08NpONF3t}*kjhM+v$2Ygmp`arm>Guo@Za0@jSxqxBXZnpvF&X=XCoYc}v7P ziC%OQeoe2@pB#S3AMi~t1nRyR(tKU<3fES(*EI`?uGSgmkL-y6Z`~J-SAI`iF&zg2 zzQED7b<-@`*TViC{??lCsE+ROH%yVPKY6nQViCZ{9+Y?{TmJwWX}8vQ8XPuot;;gJ zksY!`pp{erf_cFDX0q;J@eY*t7nho+*?!!j(%Z=@gl!!$*9t!hBNO29*y`B2uC-To z-`(VmTOAu*@m=JX+OD-{q1;S-tDA_5#@5lH_vc0RS*d{0|iqPR^ZO*lS;teY4taMqd@2v9BNjm(Y&lwBYcC9#Q^6U@N61--dm}KZj);wH}P#e@H_EP+3VgW)^3^`7<7#`)(HrbQH2uvH($Cr z{Av2-l>RqH)OBwXOZKVMLg{F^HwuG=0AzuV!lY$S5qOVJOFR8SORuthp5c-xp(XaH z;Ge|SZ-tjg7dM)QyQ^Go)er71pjHwn9sRzwYvIkdhiaFXA}inYrUKFhgvoI*8P9Ae z&06snhb}cm(lxfW+i$u^;)+j{f;bHQ@H+k!47K6g+bbJ2v(x+^HmZYR2~QHPwV|t6STqGv_R$_oYDH z-vL1Wbe|D*{TEidzWWPaYZpQh`^~wHfE#wNV0q$!+f$E&QL(%5>{nNsoR=3`dab3K zDcp@bpTy^(+Mt{c^~;Ox8&}ouKj9$MH7lzQ0;DTr=BZP>&2Sqic?m%ipDvT&hLB3sqzq~9G~v-k9<@*YU`Jt z6P0dtOM6HyWk^wBh#)QoHm~(G{VL~0@MZ3>_g7PEQ%DhKSlj&=NWv0Ew@(H~8!ZB%N1OTz*bOV!$ z?R+0&H;45vvgzI(U$X<>sLgSr+v?3{sOh%xX->h0@4mnsu|ApT zDKJ_+Oif;0bNfH+wt5}Cyf&(((az>o0Chh2>DHHDx47|tfh|?FIP61CsU%DC?mfmj zl%=qppG;(C5%E`u^#1@KM`sqFr|H(Pqokhoq%&E? zY9IbSe8xE>4_>CB_?2y=%YWgyEThzQNtJir72L@poG~3eYiHr~_p`};X4);TnQGIC zm2M;2QBOVkl0Ql=G7CK#OXOR98%2`F&cv+K8-t89bjN(+q}Q~)Q^H;_j^|g@>?~hX zxA|5q7TA4#`f=8@b+atD_fkpXIL(yPp)uQ^zE?OOhf3qVE6$q7*-ed&#pU&r@0wGc zs<|C|bf9MDocd0wY|-6)zUFA%T*wLGK|GK4f1NwSnp~1=_tR;*R5tMJVF{hF=7l)~ z`jh=@Ne75^%{WgUn`Nci>XyqGWFv42HspPO`t`|bejU^_j|e1pI>d0?TDgvK=KSL< zI3D<*W&Z#Sc&bkp_0G2+Vk4n?myfdsmt!Z(pYVg`cC?D!u1OtJNwU6Tc zavcxF5=l0v{+WFq7CTY9ry~Nibng?(d8gZ==+fOxzz;U#q8bY5Zg{WZo{pM@=9gn6 z_jeaoiq`7`5*+tq@89#L_%3Z~=S;IxqubiY9xbJsf0rPf6I=J%%#gz#tsT9tp7&5C zy33rA$;lp-$;kRmy}qUWrK{acu)3Ji2{z;&r|_wk#Fso%ti#~Y(YCq1TPuu3Z)yM~ zIV7LLve#77wZDi_`F1zY4cs1TZ&UlDL;C&X=IvY73}9V78LscWooM zKK``^xd(}s<4)BtC$rH-tZN)mHw;wcx8N#AsnFTj_=7~c)Fab$n{7Th7h#foZdE>p zvh@D|2wYx0$M)v669qzJ5zmaaa&zApd(RN~>gwL(QM$hU%FQF&f)ueIbf0Re zbD|}LcM;my-Zj;%o?w=6QCJSlKD8`IL8NH9OWU>Po2T7sSF0uhV7zBOo%p7R{7kay zmOt6T&2=HZKbPi+_N&?>_>lN`eT(cCP&4`4w}3_mZhy{eA6~z8@n(y8dE$d3T{8*7 z9Bt!)=|ezac$2{irD;)W8lI!}skHs1!RFzC&PnN3{5`Abf7(ktIz8s7X9sdHEK@z} zTgJK#o};7caoXwk*Yh|BaU?PCoO)GAwOw<=-W$^O2-Y1kIZ8sjWsj+9oorTykA*xv zt9Yi{P?9@KeI5%rgQRky3^D7TzM8b&n8zuGVNg*7BSwQ~lA8#+$1> zt+mb6nufb1;^HARzDr}w&+vsEO>?>ji*#uH00Ms(`s9bM8s$QAMO{ayGJbw71hN z?svMxRBp#nk4%cjwD7){t?6)G>zcjANJnPL`Z9;f& zNO&WYF|vAqK9x1M#R=}Oq_xwuNg6wp8w0P*efm|4t2--Oy+Yqf(jIjoi@ z#0c-zt)GnA2 zA!XbP3~}_$NLbIcUk!MFPn#ND_Mvec#78#Vt~(BELrBtf?Mm(`n)=(r_L3=dOpVwa zjOMK_zv5e+V&c{v3dYhsLI6|Fc>mft(!~HigMmKtron+=f>M9$%#)8?Y=p`J2>Ucb;* zMwxWG9X+{@H2(lry)sX)rE)j^AJRszBTcGm8j{H#hE&p7Xj=5;R;zK7uJU+ld!MX5tLRhP=#jns9b;wkuh#M*-RW;3AZ zH$HWQqjSv{?#6vU=C`#S8(lZET06|IB>MFLtl1wOd%#XF4|UlZ*=;TW-+-s1UJZNiDre6mP; zkbOGVW~-`reICYbBwSux?jCGJZy|lptwFBdX*y?#T4^->Ls7BV3dq@g?Sa?WR%MTj zb&nO=%?_WX+Ud|)xgz96w1pi8YS48ZsQ7=xpW64$29_-&yH3bJ zV9l*~k!@|jDA2+KI^&?otxq3lJ|Nbov71!!JaO9jWVF$^-5Bfz7ycIT?Z1a-SX)%p zuJDq@D-g4@C7dZbeaD9GA-0C|Si1Ys%^@LU9kMBOEA3RhrN*D4!yL++ zJlPirYq494i`}p-jjo3s)Ib)W{#pUY>s+R!w^vqIHtnz4TR{tKjUxGSJCV&)WI>g6 zZK>-|aGLh9Zya_qXUL0;l5l(R`qpNt2Zyw~h~|RE>sn^Wl#W$L<<_-zdmj$yiaeFN z)~~MPSn}*hR`0;;&1YHv0K!TC00{lXy4c(4)>gA_UCI=k^v`;s5laTCt=LKS8%5Hh zvTT5(_kbT?YRlI&yPH{8`%7GgNT&VfVQr-PDL&OFi!CFAP-WCSNxSV44a)<9yQ?lW z(`=W^v9i9@t|QL*CPTHq&lD17>o!_Bni*`YFD|a3U}W6o<8P_QtzG`t*R>0$v$wUj z(b>~}WKqUCmCw{w+j|{e6LOwyj*kq=90?cZI2jd_e|@A$1XmaL*IJb9#7VT{o|wSw zeJX}#>bfGOwXE8Qh??)qd`ld1HDXxG1A=TKR$sjF%JWVhD(UA$nfe(rz$bcrn7Xd2bpEO%ELZI!%{jlvW6 zN1^&w5YT)-EsU1yaj0KiMBgN8`9|liJu1$hr)XlvX1KW3HA|-ZvB!{%Gex$as%W~j zGg#Wiq}$zLGjN}EeNJhnJC4vb3+rt|PmfQ~ZQ!_P^0$@wBq#gX^s868KB1=Sm(c3k zv^H&qkV6wM&e34Ci%z(`vx56jzYmSYOC~*ffA#Bf*TeeS-&@^6EcBS~6h_Q`V0s<~c>2=m z@_2&lPq@>pW3|%l;{>sj3nGKtpXphXiz_QTU$<&asmX6P*0zM5pnIQMcN;8gx)qEr z&8v8lOT@Jsk{eT=2=Dn;cBOY?XBC{7~^0aN$dGjB1J3vjbm9cuBUMxkpySUQjvLVGtVE& zv!L+Clcq~>_ZOEJR-ryg6mDm4rBA3>=(m@QZZ%7dMnzES0nQJlGg{W}?`E@W9W8C+ zP*XFmeBJ=gJ5wab)Fqc)f;cp-IL5Z_Sk71GW%WJ1>o-srM)ji9HN}QGu*5__+=Wu29%(Yp`P(7wie$>g9YpE#i6L8C ztBC{c82hK+HD6d=Le=3|bmg^-ro+TMsw&5UKfz+2`>W<>`ocH}VQIUPlCp9-2^8(Zmj zTD8sQp>YcNDDzy%#bYEAoqp~~IO)xMKa9LDr+6#&ez*S1vbVE0I*ctTR1DG`ySXPP zuQk=pt&KSkHt?r|G~53Gin^|zd?y~W73^}0Em(mZWVkMkDC*d3gSQy#TH5c#&3jbS zty;>@OVa-Uv-MeR=bCv8ft&!VF74euQaR@YbHJ|>_?`Pm_}juC7ximxH(r{~8$3$} z$RgbnEK(3vw&Zm^{{WD#_x5%8aie&8vbX8{{Z1?$sFGiuPm>w6()EsXLj-#a>@e*>7CqXIK^~2*MhX0T?0p5C&HHA zCWHG*>PaEFX?Dz2P={H#=0**If9IcU*JGh+_P!oIABM`##@!@o8H!sb?5at$?#4kF z9D`iesqs_9J|Os2;w?_|RJfY*-%*BW+X||V@sh+K0eK*HtBSFoD`ZE-8r0q$)NRxL z5nl+Z=3BVuxM6V{^^CUTwb!ut}WqlyO3d$H^Vw-hWyPg&rpWVtOcBx*Y^Hp zy~OOSNa$5^08qo6)4ykJ9^Xdzmw7ZXvq-40W@l-EMfpOIo?O`+UiEyG>!a%u@+!cbbDBi2L#u&YhD`D{2$|Q2(FuBYib$gazsI!JCnJ| z?teO{yOYXgc$dWYpJ0aT!uGdKeWb@7znc?0jdH-8BeIMTxXwB6j z>P>HFq2KD!{MUMfJFR6bFw7HzFitx6u5b2)_@S@Q;)SvP(waL-H5UyOL1R;l0rx=Z zlU%oqApX(uc9(B+B-a-I0Alk*Qp(aIu>g_*Bm?xVIeQDOk5};)i{U>LJoer;@s5@K zwQFL{VP)a`NojJ<2s_g(L-qrMlUzoiZS)_AR%zjX3cPFfL2q`~Q!kk17x;104W0)k zy$9hHmA{2GYjxA@Z0-EySRDPG9f}+RGQgfic|Ywl;*0MOXczNY%&<*mePwTND2+^z zB#j_&tVUNL4nfZpNFsHf3h=LpJ}K)LI)0_%DXevPN1r{g#Brejkr^$MyKgxhQLRtl z_R-eQNx0WMM{{PS=Cz%}Myv?LX!sp@JZFmM{v2J&tM~@>t{tS3!5&B@&e>I%oy55L zn4fZM(Y^yg7N6iv2KqQH&DQBy$s|iAPCAglgVwW*uIxJw@TQ$~bn7Ve{{RZ;HnH78 zWqTXBH%y1NPB<9t$;~^(T5ZG{gm+)tR=yC@Z!LU_)v3t`?wr_HRcw+Hr2dU z@ilat>*?gM*(M`H7DD>2*M zTw2E!lyf56$YBBgUz_E}KJ+G4k6qREIW|)xRwS0ySlQX`P#0;&)W}iKB%0j#Ves2TUkm6ugqACHd#Oq% zxtiujxM^Q;8TrY_&|p>X9ctGe6|&ctO_S_PXl9Zj5{25zBio)i#!m+$nqYEz^f&rW zp#(Z!i>f`)w-VmYVA~8kKp|Dz?*PQ`D_Rc@c-O@GmA0$mU3zUMJBUnBY_@MQVsZRE z{#<$r<$e=*`&jXX#*HSWs84kF4>6Fo7j^=H&<;5~3iO|elgXgi!*6ROu|;O+@ciYO z4#MAfardw&PrD!JRUp7Gn?fbJVqbCwN^jz?H#|FC(6!;fO@b|=R zFYI;SJ?lHb`rXu8hL@(S$Lv?v(k$`q2h9Pn0X=_Om8jZgUx&Oq zKZY)nXT65TA1$W5Wya>k|nvC-%lP)aL3QfjFZn& zO?DnLvyWQ%jW(NdzGaMdb4ajcss;^!a537ccr(E|O|O77yQu7KGs2EiY_z`=)QR?q|M%wJELdw9OuKFgEs& z5AP*Trb!r_4_pCUkH#N~I@gE1b$MrJeAf2x!vRzgA;#ux@VukeKg^OKXsdLM;hk4W%+u2gV>#UC`^q!Z+|tE& zC9lFui|E_Syj#d(6DY$4JwP?dU2FH+wVu4U7nf2jWJbA_fmQSb8qQO)A1S2%5!3Xm znT^J*`o5`o3&LPW-Lc8*f#2S++RESi66(iL*FMI!bF3m1VACQmP?+^S>o38&TpC}+ z9X2>4*sWp-`HK>H?oMl4;r5Gbtb9<_t?posSXM&8PZ&5SsOPO`&2jRSV(~?V;zw&0 zp09YZhLQx5GN^={7Wb!FYI@d=)*>Gd+v!#@+=&9*ND@h;=p2mp9qYXKh>L3#zmx=j zW;TL7gKjsz8#wEqeAk?75;nE3L-wX=m8O)C$BsI2MyqnvPRrs3r={uMCX#ENVnzEr z2$F@D%r7Hyc7^GVg0mp-mxfM{e>66CnwR#1EK$cJl@Xq$j(h!T*Mf8_J3A(xJ9w65 zw`UGlCw6h3d)E{32gDbeSHv$5+uP32!*vR@sGwp)lh%%FnaVaDGl`$NpS z5>DlVNZ2Gd90TrauGT&u=PJ~JAx4IZz?L-6H}neg6Lg4P(=UxA&u zIIleTo#K1zFB|CV4Z}vhV~i?+#(tGUW~KLwd_k;R%(B_0k!z*EyCiTCls99aYKz2L zHPzRSH0yiKYE4i3LctkU*psnvI-dM`)qCstyhHIXP)o@g;yB{MqaT!T2SLSe_)5wx zGWt1SK^%%&5Zy>Yj1GHH&eeGac*@l3+Z}< zddee=+vJ$# z+GZ`Dp7k=2Ep#nQ;+++IC#PNBYL}08lb2gqWII(lE=E1-=Z7^58->;c8coI2vJpHj zDxJWNe-qlZJV~Kh+IWA&R}tF4v)SCFP`<&K*QNz#_|L@G-X62DTPuTZvs<0}6lK30 zW{cevRi4*gePSJQMz^qvagzJL)sQ-8)Ky1RxJc~vU2=QRII|d_;~@1vopO4PuXU^V zdNsMYnq~W87%XwfJ--U~-w*gtO|aAS`Qfp*Nq)|!cFgDHZ}1hLTNlvqyZ-%5q40adHZsR&B$n$elOmUC7`rjuj-;PjnP}`5*yndUuCer28O7X%Ov@w>i(Yaa$S%lsYZ9h^4iL z803x>b$x-ETjt~woE`;ozAEvKsi@g$t2N}zzDaH{ry%-@r?E1NT9IoSex>DUHu{F8 zX{6fQ+zccjD=!?8>sj9ukB9E;^$26SzST7%s@CqxSPXZ@D%XQ7V$|dNRl@oA5zaQe zgs~lcYqz_xhReq=G*H5&tk|EBdRBbb1*yjPGvX!IjbUYHZKK<*)x)M{nQ^^={{TEx zpBJ=05Nc8Cx}El=Yp2I2B_cm~p1J4rt|I4Jy40_uj%l5iIag>OF5JJhb=qc^2BodF zy~4E6$*{7!mIp2MqEA6dSTr4D!#YZ=amlD%MKz#`KC)%TH-2>{p{{ARc2UV`pxrcj zY>47UhYDY~s+z5&dNTNWOH^20Tnw+Fd>$*H*Ste{W24=yQ*Bm|(bB;+pz^$(ec*9%PuC)srT^7dOZQ=8!k>keDNd0^M70=vwg7ZS~ zC5(2G`71Ln;1PNGy~T6BC-HuyH7!y_yqRC@$hlLujOVw~k7n7T*y=UKg3rYIZQiA? znJumZCBj7ee4zAG*n%C{u6I^X_0A}MGeFxU2(!3|8jcZts z>~QT^!vVLUBa=^3lDV5@28*KV+HRo?GhHN~yO6$H%sA=o&28W7H`80{mO3AY$dRKi z*Afk$S3KbKt)CNVw)X!34)k`87}dVeNg#4?1}h8V--|UHPZvjJ71WX1$Q4>Oz)}xd zR=NpB!*yFtYVy-YlT+4hl@)xqNaO=(!0%bgG+i4=oxGc^TKX9e*~aq9fE@Z_ufgG4 z5A2B8+wLOaP;Pc?E_!lm?~0`V0EBzPxAIx6cJ8o%3ZUaB2dJovxYSKcKM-qrl+fQS zI%bb)c@L93yTcAgZ1=89`!dW}>M-hB=h~VRy51XSAHE>+Yn;(9=J95+rrPQf$#HKP z`C~1$Mm>fr*ff6vX!d?B)S-`0w^;4$RihZr(m>5t!m-BN_~_gCX4Skq;oIw`QX`sc zl{-tGn9eGWgFdz6Jx=b=Uc9u??dAPvH$N*Fd~z>}|uP+aO}Qn*a<9o@$50JNaxb zw?N)YTtv$ujY97mfX5XpT~M}UdbPg0;$3dpt~_0(*}c?TCs?QXPyx#0)~IS88_@ha zq1;)+e{@Gn;E=CuXuM&hfmWjY;Eod`$N7AjD&%>gU}AO%ji1gqkR-dfnr4`)K3s)ifyM_F=}(|pXtU`s+S^AQa@sL*joXep=9TQm;(7hOlIgb! z+CPS+y7F7gX`7U8{ZI3#F4x3Y+WqB|&0}KH0U_rRrhV&QR`G75X$Glh9n(i{3Y~#R z_r95~Mh!kadg2+b{Mn?Da>UBRJbM~)mX|ZrVfVIrRgSkDm)F-C+=LG`5&lx$Fg}#^ zuxp!nq0@92;gT6QhI8|;d}6!ZKTEaIw3cgIdw5zss-#9Z7_U6>kBBcDUXnkwI;4!d zf`GZ_9Y-}v=9cJdmb|dlVTV_~hRtrG+DvEerUpUxtci||pJND~2Kb;DjYp+Z@fV1% zwf_JaEEjiD%M5d2R2`rWeKF`OsEXD!(j;6QM>z|YCmlb=jkF}s)2v(0Z|tou3x=9J z;!~DyaaId>i%-yDby#d-wD|xD^C|1o-nrk1{wmZojb=5qx{?7LY8PMw9D(UsYpC36 zSF;)CnoY~Ng6A2|Gme#`rqUNN*(J7~vU&QxwAT$k%;gUto^i)drB#X}XJ>r6ev>8B zXU&djK3oCq--_(Vg7m8|2KZL)D;QSd==qYqId<8cn&Z4%;%ogkRn!s-nIl$1kTHYW zvx%zY*VC>vtCM+{qj<&O)m2 z2l>r!X_`&7#*WP-DDAYi;xcpfs^zg4IqgdN!aY*m?d@-`7iP!vvQ^vI;;1AVgtN}B z&}ooH=1q;)9>TBq`%;@p@cXU1`AZL$$%P*&D#Y{k6~Jk?(`x#RZFM8gTX;LpbH!DN zo3gpFe{*dn*P8xIm41Af+o0`KZmuDMZz3HnzHyW+I@d*UpxNm@5}xAT6^>>km&qqP zhp*PSJx^b}zLMQ#ottE=i+~0ONbOe`lT$}yTT|7prH&QE7I5v_yHCtMxvKvFWRL!W o5!E|8NbWB$QbpdeMU(`Sx1~e1f9I4R_vwGapD7Zn818@n*-&{c)&Kwi literal 0 HcmV?d00001 diff --git a/bsp/apollo2/applications/SConscript b/bsp/apollo2/applications/SConscript index 01eb940dfb..fc2501998c 100644 --- a/bsp/apollo2/applications/SConscript +++ b/bsp/apollo2/applications/SConscript @@ -2,8 +2,8 @@ Import('RTT_ROOT') Import('rtconfig') from building import * -cwd = os.path.join(str(Dir('#')), 'applications') -src = Glob('*.c') +cwd = os.path.join(str(Dir('#')), 'applications') +src = Glob('*.c') CPPPATH = [cwd, str(Dir('#'))] group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) diff --git a/bsp/apollo2/applications/main.c b/bsp/apollo2/applications/main.c index dab3fd123f..b058fc7711 100644 --- a/bsp/apollo2/applications/main.c +++ b/bsp/apollo2/applications/main.c @@ -1,5 +1,5 @@ /* - * File : application.c + * File : main.c * This file is part of RT-Thread RTOS * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * @@ -23,7 +23,7 @@ */ #include -#include + #ifdef RT_USING_FINSH #include #include diff --git a/bsp/apollo2/board/Sconscript b/bsp/apollo2/board/Sconscript index aa1e87d860..2f2dc9eb48 100644 --- a/bsp/apollo2/board/Sconscript +++ b/bsp/apollo2/board/Sconscript @@ -2,8 +2,8 @@ Import('RTT_ROOT') Import('rtconfig') from building import * -cwd = GetCurrentDir() -src = Glob('*.c') +cwd = GetCurrentDir() +src = Glob('*.c') CPPPATH = [cwd] #remove other no use files diff --git a/bsp/apollo2/board/board.c b/bsp/apollo2/board/board.c index 8e1c3b8e88..d9e202570b 100644 --- a/bsp/apollo2/board/board.c +++ b/bsp/apollo2/board/board.c @@ -1,11 +1,21 @@ /* * File : board.c * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2009 RT-Thread Develop Team + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -19,11 +29,23 @@ #include "am_mcu_apollo.h" #include "hal/am_hal_clkgen.h" #include "hal/am_hal_cachectrl.h" -#include "hw_uart.h" +#include "uart.h" +#include "led.h" + +#ifdef __CC_ARM +extern int Image$$RW_IRAM1$$ZI$$Limit; +#define AM_SRAM_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit) +#elif __ICCARM__ +#pragma section="HEAP" +#define AM_SRAM_BEGIN (__segment_end("HEAP")) +#else +extern int __bss_end; +#define NRF_SRAM_BEGIN (&__bss_end) +#endif #define TICK_RATE_HZ RT_TICK_PER_SECOND #define SYSTICK_CLOCK_HZ ( 32768UL ) -#define WAKE_INTERVAL ( (uint32_t) ((SYSTICK_CLOCK_HZ / TICK_RATE_HZ)) ) +#define WAKE_INTERVAL ( (uint32_t) ((SYSTICK_CLOCK_HZ / TICK_RATE_HZ))) /** * This is the timer interrupt service routine. @@ -34,16 +56,16 @@ void am_stimer_cmpr0_isr(void) /* Check the timer interrupt status */ am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREA); am_hal_stimer_compare_delta_set(0, WAKE_INTERVAL); - + if (rt_thread_self() != RT_NULL) { - /* enter interrupt */ - rt_interrupt_enter(); + /* enter interrupt */ + rt_interrupt_enter(); - rt_tick_increase(); + rt_tick_increase(); - /* leave interrupt */ - rt_interrupt_leave(); + /* leave interrupt */ + rt_interrupt_leave(); } } @@ -53,13 +75,10 @@ void am_stimer_cmpr0_isr(void) */ void SysTick_Configuration(void) { - /* Set the main clk */ - am_hal_clkgen_sysclk_select(AM_HAL_CLKGEN_SYSCLK_MAX); - /* Enable compare A interrupt in STIMER */ am_hal_stimer_int_enable(AM_HAL_STIMER_INT_COMPAREA); - /* Enable the timer interrupt in the NVIC */ + /* Enable the timer interrupt in the NVIC, making sure to use the appropriate priority level */ am_hal_interrupt_enable(AM_HAL_INTERRUPT_STIMER_CMPR0); /* Configure the STIMER and run */ @@ -69,15 +88,6 @@ void SysTick_Configuration(void) AM_HAL_STIMER_CFG_COMPARE_A_ENABLE); } -/** - * This is the CacheCtrl Enable. - * - */ -void CacheCtrl_Enable(void) -{ - am_hal_cachectrl_enable(&am_hal_cachectrl_defaults); -} - /** * This is the low power operation. * This function enables several power-saving features of the MCU, and @@ -100,7 +110,7 @@ void am_low_power_init(void) /* Stop the XT and LFRC */ am_hal_clkgen_osc_stop(AM_HAL_CLKGEN_OSC_XT); - // am_hal_clkgen_osc_stop(AM_HAL_CLKGEN_OSC_LFRC); + am_hal_clkgen_osc_stop(AM_HAL_CLKGEN_OSC_LFRC); /* Disable the RTC */ am_hal_rtc_osc_disable(); @@ -112,7 +122,11 @@ void am_low_power_init(void) */ void deep_power_save(void) { - am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP); + am_hal_interrupt_master_disable(); + + am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP); + + am_hal_interrupt_master_enable(); } /** @@ -120,27 +134,48 @@ void deep_power_save(void) */ void rt_hw_board_init(void) { - /* Set the clock frequency */ - SysTick_Configuration(); - - /* Set the default cache configuration */ - CacheCtrl_Enable(); + /* Set the system clock to maximum frequency */ + am_hal_clkgen_sysclk_select(AM_HAL_CLKGEN_SYSCLK_MAX); + + /* Set the default cache configuration */ + am_hal_cachectrl_enable(&am_hal_cachectrl_defaults); /* Configure the board for low power operation */ - //am_low_power_init(); - -#ifdef RT_USING_IDLE_HOOK - rt_thread_idle_sethook(deep_power_save); + am_low_power_init(); + + /* Config SysTick */ + SysTick_Configuration(); + +#ifdef RT_USING_IDLE_HOOK + /* Set sleep deep mode */ + rt_thread_idle_sethook(deep_power_save); + +#ifndef NO_FPU + /* 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 - + + /* Turn off unused Flash & SRAM */ + am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEMEN_FLASH512K); + am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEMEN_SRAM32K); + +#endif + #ifdef RT_USING_CONSOLE - rt_hw_uart_init(); + rt_hw_uart_init(); rt_console_set_device(RT_CONSOLE_DEVICE_NAME); #endif #ifdef RT_USING_COMPONENTS_INIT rt_components_board_init(); #endif + +#ifdef RT_USING_HEAP + rt_system_heap_init((void*)AM_SRAM_BEGIN, (void*)AM_SRAM_END); +#endif } /*@}*/ diff --git a/bsp/apollo2/board/board.h b/bsp/apollo2/board/board.h index 8bafd7dfa2..a93892c3b2 100644 --- a/bsp/apollo2/board/board.h +++ b/bsp/apollo2/board/board.h @@ -1,16 +1,45 @@ +/* + * File : board.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-09-14 Haley first implementation + */ #ifndef __BOARD_H_ #define __BOARD_H_ #include // Internal SRAM memory size[Kbytes] <8-256> -// Default: 256 +// Default: 256 #define AM_SRAM_SIZE 256 #define AM_SRAM_END (0x10000000 + AM_SRAM_SIZE * 1024) /* USART driver select. */ #define RT_USING_UART0 -#define RT_USING_UART1 +//#define RT_USING_UART1 + +/* LED driver select. */ +#define RT_USING_LED0 +//#define RT_USING_LED1 +//#define RT_USING_LED2 +//#define RT_USING_LED3 void rt_hw_board_init(void); diff --git a/bsp/apollo2/board/led.c b/bsp/apollo2/board/led.c index bb8d1e1532..1cf68b5605 100644 --- a/bsp/apollo2/board/led.c +++ b/bsp/apollo2/board/led.c @@ -43,6 +43,7 @@ */ void rt_hw_led_on(rt_uint8_t LEDNum) { +#ifdef RT_USING_PIN if(LEDNum == 0) rt_pin_write(AM_GPIO_LED0, PIN_LOW); @@ -54,6 +55,7 @@ void rt_hw_led_on(rt_uint8_t LEDNum) else if(LEDNum == 3) rt_pin_write(AM_GPIO_LED3, PIN_LOW); +#endif } /** @@ -67,6 +69,7 @@ void rt_hw_led_on(rt_uint8_t LEDNum) */ void rt_hw_led_off(rt_uint8_t LEDNum) { +#ifdef RT_USING_PIN if(LEDNum == 0) rt_pin_write(AM_GPIO_LED0, PIN_HIGH); @@ -78,6 +81,7 @@ void rt_hw_led_off(rt_uint8_t LEDNum) else if(LEDNum == 3) rt_pin_write(AM_GPIO_LED3, PIN_HIGH); +#endif } /** @@ -91,6 +95,7 @@ void rt_hw_led_off(rt_uint8_t LEDNum) */ int rt_hw_led_init(void) { +#ifdef RT_USING_PIN #if defined(RT_USING_LED0) /* config led */ rt_pin_mode(AM_GPIO_LED0, PIN_MODE_OUTPUT); @@ -122,10 +127,10 @@ int rt_hw_led_init(void) /* turns off the led */ rt_hw_led_off(3); #endif /* RT_USING_LED1 */ - +#endif return 0; } -#ifdef RT_USING_PIN +#ifdef RT_USING_COMPONENTS_INIT INIT_BOARD_EXPORT(rt_hw_led_init); #endif diff --git a/bsp/apollo2/rtconfig.h b/bsp/apollo2/rtconfig.h index 759cd4078a..6126e294fa 100644 --- a/bsp/apollo2/rtconfig.h +++ b/bsp/apollo2/rtconfig.h @@ -16,14 +16,14 @@ /* SECTION: RT_DEBUG */ /* Thread Debug */ -#define RT_DEBUG +//#define RT_DEBUG //#define RT_DEBUG_INIT 1 -#define RT_USING_OVERFLOW_CHECK +//#define RT_USING_OVERFLOW_CHECK /* Using Hook */ //#define RT_USING_HOOK -//#define RT_USING_IDLE_HOOK +#define RT_USING_IDLE_HOOK #define IDLE_THREAD_STACK_SIZE 384 @@ -60,6 +60,9 @@ #define RT_USING_SMALL_MEM #define RT_USING_TINY_SIZE +/* Using USER MAIN */ +#define RT_USING_USER_MAIN + // #define RT_USING_COMPONENTS_INIT @@ -78,13 +81,16 @@ // #define RT_CONSOLE_DEVICE_NAME "uart0" +/* Using GPIO pin framework */ +#define RT_USING_PIN + // #define RT_USING_SPI /* SECTION: finsh, a C-Express shell */ #define RT_USING_FINSH /* configure finsh parameters */ #define FINSH_THREAD_PRIORITY 6 -#define FINSH_THREAD_STACK_SIZE 512 +#define FINSH_THREAD_STACK_SIZE 1024 #define FINSH_HISTORY_LINES 1 /* Using symbol table */ #define FINSH_USING_SYMTAB From 96b1da173edb42aab35d65cbd27ba982ce278a70 Mon Sep 17 00:00:00 2001 From: lin <429426691@qq.com> Date: Wed, 20 Sep 2017 12:42:23 +0800 Subject: [PATCH 5/5] Modified not use c99 --- bsp/apollo2/board/uart.c | 13 +++--- .../libraries/drivers/hal/am_hal_cachectrl.c | 24 +++++------ bsp/apollo2/project.uvprojx | 40 ++++++++++++------- bsp/apollo2/template.uvprojx | 6 +-- 4 files changed, 47 insertions(+), 36 deletions(-) diff --git a/bsp/apollo2/board/uart.c b/bsp/apollo2/board/uart.c index 80a8f98d1d..3a9242ab55 100644 --- a/bsp/apollo2/board/uart.c +++ b/bsp/apollo2/board/uart.c @@ -55,11 +55,11 @@ struct am_uart */ am_hal_uart_config_t g_sUartConfig = { - .ui32BaudRate = 115200, - .ui32DataBits = AM_HAL_UART_DATA_BITS_8, - .bTwoStopBits = false, - .ui32Parity = AM_HAL_UART_PARITY_NONE, - .ui32FlowCtrl = AM_HAL_UART_FLOW_CTRL_NONE, + 115200, // ui32BaudRate + AM_HAL_UART_DATA_BITS_8, // ui32DataBits + false, // bTwoStopBits + AM_HAL_UART_PARITY_NONE, // ui32Parity + AM_HAL_UART_FLOW_CTRL_NONE, // ui32FlowCtrl }; /** @@ -246,9 +246,10 @@ static int am_getc(struct rt_serial_device *serial) static void uart_isr(struct rt_serial_device *serial) { uint32_t status; + struct am_uart* uart; RT_ASSERT(serial != RT_NULL); - struct am_uart *uart = (struct am_uart *) serial->parent.user_data; + uart = (struct am_uart *) serial->parent.user_data; RT_ASSERT(uart != RT_NULL); diff --git a/bsp/apollo2/libraries/drivers/hal/am_hal_cachectrl.c b/bsp/apollo2/libraries/drivers/hal/am_hal_cachectrl.c index 23c7164418..26c41a22e3 100644 --- a/bsp/apollo2/libraries/drivers/hal/am_hal_cachectrl.c +++ b/bsp/apollo2/libraries/drivers/hal/am_hal_cachectrl.c @@ -57,18 +57,18 @@ //***************************************************************************** const am_hal_cachectrl_config_t am_hal_cachectrl_defaults = { - .ui32EnableCache = 1, - .ui32LRU = 0, - .ui32EnableNCregions = 0, - .ui32Config = AM_HAL_CACHECTRL_CACHECFG_CONFIG_2WAY_512, - .ui32SerialCacheMode = 0, - .ui32FlashCachingEnables = 3, - .ui32EnableCacheClockGating = 1, - .ui32EnableLightSleep = 0, - .ui32Dly = 1, - .ui32SMDly = 1, - .ui32EnableDataClockGating = 1, - .ui32EnableCacheMonitoring = 0, + 1, // ui32EnableCache + 0, // ui32LRU + 0, // ui32EnableNCregions + AM_HAL_CACHECTRL_CACHECFG_CONFIG_2WAY_512, // ui32Config + 0, // ui32SerialCacheMode + 3, // ui32FlashCachingEnables + 1, // ui32EnableCacheClockGating + 0, // ui32EnableLightSleep + 1, // ui32Dly + 1, // ui32SMDly + 1, // ui32EnableDataClockGating + 0, // ui32EnableCacheMonitoring }; //***************************************************************************** diff --git a/bsp/apollo2/project.uvprojx b/bsp/apollo2/project.uvprojx index 6e5bcba4b4..a528b27b90 100644 --- a/bsp/apollo2/project.uvprojx +++ b/bsp/apollo2/project.uvprojx @@ -79,7 +79,7 @@ 0 - 0 + 1 0 fromelf --bin !L --output rtthread.bin @@ -354,7 +354,7 @@ 1 0 0 - 1 + 0 0 0 0 @@ -363,7 +363,7 @@ 2 0 0 - 1 + 0 0 1 1 @@ -373,7 +373,7 @@ AM_PART_APOLLO2, AM_PACKAGE_BGA, keil - applications;.;board;libraries\drivers;libraries\startup;..\..\include;..\..\libcpu\arm\cortex-m4;..\..\libcpu\arm\common;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\finsh + applications;.;board;libraries\drivers;libraries\startup;..\..\include;..\..\libcpu\arm\cortex-m4;..\..\libcpu\arm\common;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\finsh @@ -417,34 +417,39 @@ Applications - application.c + main.c 1 - applications\application.c - - - startup.c - 1 - applications\startup.c + applications\main.c Board + + adc.c + 1 + board\adc.c + board.c 1 board\board.c - hw_led.c + gpio.c 1 - board\hw_led.c + board\gpio.c - hw_uart.c + led.c 1 - board\hw_uart.c + board\led.c + + + uart.c + 1 + board\uart.c @@ -626,6 +631,11 @@ DeviceDrivers + + pin.c + 1 + ..\..\components\drivers\misc\pin.c + serial.c 1 diff --git a/bsp/apollo2/template.uvprojx b/bsp/apollo2/template.uvprojx index eef72b7995..29ce82bf53 100644 --- a/bsp/apollo2/template.uvprojx +++ b/bsp/apollo2/template.uvprojx @@ -79,7 +79,7 @@ 0 - 0 + 1 0 fromelf --bin !L --output rtthread.bin @@ -354,7 +354,7 @@ 1 0 0 - 1 + 0 0 0 0 @@ -363,7 +363,7 @@ 2 0 0 - 1 + 0 0 1 1