Merge branch 'master'
[fw/altos] / src / samd21 / ao_arch.h
diff --git a/src/samd21/ao_arch.h b/src/samd21/ao_arch.h
new file mode 100644 (file)
index 0000000..a5f68da
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * Copyright © 2019 Keith Packard <keithp@keithp.com>
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_ARCH_H_
+#define _AO_ARCH_H_
+
+#include <stdio.h>
+#include <samd21.h>
+
+/*
+ * Samd21 definitions and code fragments for AltOS
+ */
+
+#define AO_PORT_TYPE   uint32_t
+
+#define AO_LED_TYPE    AO_PORT_TYPE
+
+#define ao_arch_naked_declare  __attribute__((naked))
+#define ao_arch_naked_define
+
+#define ao_arch_reboot() \
+       (samd21_scb.aircr = ((SAMD21_SCB_AIRCR_VECTKEY_KEY << SAMD21_SCB_AIRCR_VECTKEY) | \
+                         (1 << SAMD21_SCB_AIRCR_SYSRESETREQ)))
+
+#define ao_arch_nop()          asm("nop")
+#define ao_arch_interrupt(n)   /* nothing */
+#define ao_arch_block_interrupts()     asm("cpsid i")
+#define ao_arch_release_interrupts()   asm("cpsie i")
+
+/* ao_romconfig.c */
+#define AO_ROMCONFIG_SYMBOL __attribute__((section(".init.1"))) const
+#define AO_USBCONFIG_SYMBOL __attribute__((section(".init.2"))) const
+
+/*
+ * ao_timer.c
+ *
+ * For the samd21, we want to use the DFLL48 clock
+ */
+
+/* GCLK 0 is always the system clock source */
+
+#define AO_GCLK_SYSCLK 0
+
+/* If there's a 32kHz xtal, use that for the 32kHz oscillator */
+#ifdef AO_XOSC32K
+# ifndef AO_GCLK_XOSC32K
+#  define AO_GCLK_XOSC32K      1
+# endif
+#endif
+
+/* If there's a high-freq xtal, use that */
+#ifdef AO_XOSC
+# ifndef AO_GCLK_XOSC
+#  define AO_GCLK_XOSC 1
+# endif
+
+# ifndef AO_XOSC_GCLK_DIV
+#  define AO_XOSC_GCLK_DIV 1
+# endif
+
+# define AO_FDPLL96M   ((AO_XOSC_FREQ / AO_XOSC_DIV * AO_XOSC_MUL) / AO_XOSC_GCLK_DIV)
+
+/* By default, use the xosc for the system, but allow the dfll48m to
+ * drive USB if desired.
+ */
+
+# ifndef AO_GCLK_FDPLL96M
+#  define AO_SYSCLK            AO_FDPLL96M
+#  define AO_GCLK_FDPLL96M     AO_GCLK_SYSCLK
+#  define AO_GCLK_DFLL48M      2
+# endif
+
+#endif /* AO_XOSC */
+
+#if AO_DFLL48M
+# ifndef AO_GCLK_DFLL48M
+#  define AO_SYSCLK    AO_DFLL48M
+#  define AO_GCLK_DFLL48M AO_GCLK_SYSCLK
+# endif
+#endif
+
+#ifndef AO_GCLK_USB
+# if AO_DFLL48M
+#  define AO_GCLK_USB AO_GCLK_DFLL48M
+# else
+#  define AO_GCLK_USB AO_GCLK_SYSCLK
+# endif
+#endif
+
+/*
+ * ao_timer.c
+ *
+ * For the samd21, we want to use the DFLL48 clock
+ */
+
+/* GCLK 0 is always the system clock source */
+
+#define AO_GCLK_SYSCLK 0
+
+/* If there's a 32kHz xtal, use that for the 32kHz oscillator */
+#ifdef AO_XOSC32K
+# ifndef AO_GCLK_XOSC32K
+#  define AO_GCLK_XOSC32K      1
+# endif
+#endif
+
+/* If there's a high-freq xtal, use that */
+#ifdef AO_XOSC
+# ifndef AO_GCLK_XOSC
+#  define AO_GCLK_XOSC 1
+# endif
+
+# ifndef AO_XOSC_GCLK_DIV
+#  define AO_XOSC_GCLK_DIV 1
+# endif
+
+# define AO_FDPLL96M   ((AO_XOSC_FREQ / AO_XOSC_DIV * AO_XOSC_MUL) / AO_XOSC_GCLK_DIV)
+
+/* By default, use the xosc for the system, but allow the dfll48m to
+ * drive USB if desired.
+ */
+
+# ifndef AO_GCLK_FDPLL96M
+#  define AO_SYSCLK            AO_FDPLL96M
+#  define AO_GCLK_FDPLL96M     AO_GCLK_SYSCLK
+#  define AO_GCLK_DFLL48M      2
+# endif
+
+#endif /* AO_XOSC */
+
+#if AO_DFLL48M
+# ifndef AO_GCLK_DFLL48M
+#  define AO_SYSCLK    AO_DFLL48M
+#  define AO_GCLK_DFLL48M AO_GCLK_SYSCLK
+# endif
+#endif
+
+#ifndef AO_GCLK_USB
+# if AO_DFLL48M
+#  define AO_GCLK_USB AO_GCLK_DFLL48M
+# else
+#  define AO_GCLK_USB AO_GCLK_SYSCLK
+# endif
+#endif
+
+#define AO_HCLK                (AO_SYSCLK / AO_AHB_PRESCALER)
+
+#define AO_HCLK                (AO_SYSCLK / AO_AHB_PRESCALER)
+#define AO_PCLK                (AO_HCLK / AO_APB_PRESCALER)
+#define AO_SYSTICK     (AO_HCLK)
+#define AO_PANIC_DELAY_SCALE  (AO_SYSCLK / 12000000)
+
+#define AO_SAMD21_NVIC_HIGH_PRIORITY   (0 << 6)
+#define AO_SAMD21_NVIC_CLOCK_PRIORITY  (1 << 6)
+#define AO_SAMD21_NVIC_MED_PRIORITY    (2 << 6)
+#define AO_SAMD21_NVIC_LOW_PRIORITY    (3 << 6)
+
+/* ADC maximum reported value */
+#define AO_ADC_MAX                     4095
+
+#define AO_SAMD21_NVIC_HIGH_PRIORITY   (0 << 6)
+#define AO_SAMD21_NVIC_CLOCK_PRIORITY  (1 << 6)
+#define AO_SAMD21_NVIC_MED_PRIORITY    (2 << 6)
+#define AO_SAMD21_NVIC_LOW_PRIORITY    (3 << 6)
+
+/* ADC maximum reported value */
+#define AO_ADC_MAX                     4095
+
+/* This has to be 65536 so that TCC and TC match; TC isn't configurable */
+#define AO_TCC_PERIOD          65536
+#define SNEK_PWM_MAX           (AO_TCC_PERIOD-1)
+
+#define AO_TICK_TYPE           uint32_t
+#define AO_TICK_SIGNED         int32_t
+
+bool
+ao_usb_waiting(void);
+
+#define AO_CMD_LEN             128
+
+#ifndef AO_STACK_SIZE
+#define AO_STACK_SIZE          512
+#endif
+
+#ifndef HAS_BOOT_LOADER
+#define HAS_BOOT_LOADER                        1
+#endif
+
+#if HAS_BOOT_LOADER
+#define AO_BOOT_APPLICATION_BASE       ((uint32_t *) 0x00001000)
+#ifndef AO_BOOT_APPLICATION_BOUND
+#define AO_BOOT_APPLICATION_BOUND      ((uint32_t *) (0x00000000 + samd21_flash_size()))
+#endif
+#define AO_BOOT_LOADER_BASE            ((uint32_t *) 0x00000000)
+#endif
+
+#endif /* _AO_ARCH_H_ */