diff --git a/include/libopencm3/swm050/clk.h b/include/libopencm3/swm050/clk.h
new file mode 100644
index 00000000..417fa37a
--- /dev/null
+++ b/include/libopencm3/swm050/clk.h
@@ -0,0 +1,55 @@
+/** @defgroup clk_defines Clock Defines
+ *
+ * @brief Defined Constants and Types for the SWM050 System Clock
+ *
+ * @ingroup SWM050_defines
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2019 Caleb Szalacinski
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+/**@{*/
+#ifndef LIBOPENCM3_CLK_H
+#define LIBOPENCM3_CLK_H
+#include
+#include
+
+/* Clock speed definitions */
+/** @defgroup clk_speeds Base Clock Speeds
+@{*/
+enum clk_speeds {
+ CLK_18MHZ,
+ CLK_36MHZ
+};
+/*@}*/
+
+/* Clock divider mask */
+/** @defgroup clk_mask Mask used to set the clock divider
+@{*/
+#define CLK_MASK 0xFFFFFC00
+/*@}*/
+
+BEGIN_DECLS
+
+void clk_speed(enum clk_speeds mhz, uint16_t div);
+
+END_DECLS
+
+#endif
+/**@}*/
diff --git a/include/libopencm3/swm050/flash.h b/include/libopencm3/swm050/flash.h
new file mode 100644
index 00000000..4c01ea7d
--- /dev/null
+++ b/include/libopencm3/swm050/flash.h
@@ -0,0 +1,42 @@
+/** @defgroup flash_defines Flash Defines
+ *
+ * @brief Defined Constants and Types for the SWM050 Flash API
+ *
+ * @ingroup SWM050_defines
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2019 Caleb Szalacinski
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+/**@{*/
+#ifndef LIBOPENCM3_FLASH_H
+#define LIBOPENCM3_FLASH_H
+
+#include
+
+BEGIN_DECLS
+
+uint32_t flash_write(uint32_t *dest, uint32_t *src, uint8_t cnt);
+uint32_t flash_read(uint32_t *src, uint32_t *dest, uint8_t cnt);
+uint32_t flash_erase(void);
+
+END_DECLS
+
+#endif
+/**@}*/
diff --git a/include/libopencm3/swm050/gpio.h b/include/libopencm3/swm050/gpio.h
index f54ec44d..8b01a2e3 100644
--- a/include/libopencm3/swm050/gpio.h
+++ b/include/libopencm3/swm050/gpio.h
@@ -10,6 +10,7 @@
* This file is part of the libopencm3 project.
*
* Copyright (C) 2019 Icenowy Zheng
+ * Copyright (C) 2019 Caleb Szalacinski
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -24,18 +25,14 @@
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see .
*/
-
/**@{*/
-
#ifndef LIBOPENCM3_GPIO_H
#define LIBOPENCM3_GPIO_H
-
#include
#include
/* GPIO number definitions (for convenience) */
/** @defgroup gpio_pin_id GPIO Pin Identifiers
-
@{*/
#define GPIO0 (1 << 0)
#define GPIO1 (1 << 1)
@@ -53,46 +50,62 @@
/* GPIO direction definitions */
/** @defgroup gpio_dir GPIO Pin Direction
@{*/
-#define GPIO_INPUT 0x0
-#define GPIO_OUTPUT 0x1
+enum gpio_dir {
+ GPIO_INPUT,
+ GPIO_OUTPUT
+};
/**@}*/
+/* GPIO polarity definitions */
+/** @defgroup gpio_pol GPIO Polarity
+@{*/
+enum gpio_pol {
+ GPIO_POL_LOW,
+ GPIO_POL_HIGH
+};
+/*@}*/
+
+/* GPIO interrupt trigger definitions */
+/** @defgroup gpio_trig_type GPIO Interrupt Trigger Type
+@{*/
+enum gpio_trig_type {
+ GPIO_TRIG_LEVEL,
+ GPIO_TRIG_EDGE
+};
+/*@}*/
+
+/* GPIO interrupt mask definitions */
+/** @defgroup gpio_int_masked GPIO Interrupt Mask
+@{*/
+enum gpio_int_masked {
+ GPIO_UNMASKED,
+ GPIO_MASKED
+};
+/*@}*/
+
+/* GPIO Registers */
/** @defgroup gpio_registers GPIO Registers
@{*/
/** Data register */
-#define GPIO_DATA MMIO32(GPIO_BASE + 0x0)
+#define GPIO_ADATA MMIO32(GPIO_BASE + 0x0)
/** Direction register */
-#define GPIO_DIR MMIO32(GPIO_BASE + 0x4)
+#define GPIO_ADIR MMIO32(GPIO_BASE + 0x4)
/** Interrupt enable register */
-#define GPIO_INTEN MMIO32(GPIO_BASE + 0x30)
+#define GPIO_INTEN_A MMIO32(GPIO_BASE + 0x30)
/** Interrupt mask register */
-#define GPIO_INTMASK MMIO32(GPIO_BASE + 0x34)
+#define GPIO_INTMASK_A MMIO32(GPIO_BASE + 0x34)
/** Interrupt trigger mode register */
-#define GPIO_INTLEVEL MMIO32(GPIO_BASE + 0x38)
+#define GPIO_INTLEVEL_A MMIO32(GPIO_BASE + 0x38)
/** Interrupt polarity register */
-#define GPIO_INTPOLARITY MMIO32(GPIO_BASE + 0x3c)
+#define GPIO_INTPOLARITY_A MMIO32(GPIO_BASE + 0x3c)
/** Interrupt status after masking */
-#define GPIO_INTSTATUS MMIO32(GPIO_BASE + 0x40)
+#define GPIO_INTSTAT_A MMIO32(GPIO_BASE + 0x40)
/** Interrupt status before masking */
-#define GPIO_INTRAWSTATUS MMIO32(GPIO_BASE + 0x44)
+#define GPIO_RAWINTSTAT_A MMIO32(GPIO_BASE + 0x44)
/** Interrupt clear register */
-#define GPIO_INTEOI MMIO32(GPIO_BASE + 0x48)
+#define GPIO_INTEOI_A MMIO32(GPIO_BASE + 0x48)
/** External register (wat) */
-#define GPIO_EXT MMIO32(GPIO_BASE + 0x4c)
-
-/**@}*/
-
-/** @defgroup syscon_register SYSCON Registers
- * @note These registers are really part of the SYSCON system control space
- * @{*/
-/** SWD Enable register */
-#define SWD_SEL MMIO32(SYSTEM_CON_BASE + 0x30)
-/** GPIO Alternat function selection register */
-#define GPIO_SEL MMIO32(SYSTEM_CON_BASE + 0x80)
-/** GPIO Pull up register */
-#define GPIO_PULLUP MMIO32(SYSTEM_CON_BASE + 0x90)
-/** GPIO Input enable register */
-#define GPIO_INEN MMIO32(SYSTEM_CON_BASE + 0xe0)
+#define GPIO_AEXT MMIO32(GPIO_BASE + 0x4c)
/*@}*/
BEGIN_DECLS
@@ -104,13 +117,16 @@ void gpio_toggle(uint16_t gpios);
void gpio_input(uint16_t gpios);
void gpio_output(uint16_t gpios);
-void gpio_sel_af(uint16_t gpios, bool af_en);
-void gpio_pullup(uint16_t gpios, bool en);
-void gpio_in_en(uint16_t gpios, bool en);
-void gpio_sel_swd(bool en);
+void gpio_int_enable(uint16_t gpios, bool en);
+void gpio_int_mask(uint16_t gpios, enum gpio_int_masked masked);
+void gpio_int_type(uint16_t gpios, enum gpio_trig_type type);
+void gpio_int_pol(uint16_t gpios, enum gpio_pol pol);
+uint16_t gpio_int_status(void);
+uint16_t gpio_int_raw_status(void);
+void gpio_int_clear(uint16_t gpios);
END_DECLS
#endif
-/**@}*/
\ No newline at end of file
+/**@}*/
diff --git a/include/libopencm3/swm050/memorymap.h b/include/libopencm3/swm050/memorymap.h
index 97fe23df..8f76ba7e 100644
--- a/include/libopencm3/swm050/memorymap.h
+++ b/include/libopencm3/swm050/memorymap.h
@@ -1,3 +1,11 @@
+/** @defgroup mmap_defines Memory Map
+ *
+ * @brief Defined Constants for the SWM050 Memory Map
+ *
+ * @ingroup SWM050_defines
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
/*
* This file is part of the libopencm3 project.
*
@@ -16,13 +24,14 @@
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see .
*/
-
+/**@{*/
#ifndef LIBOPENCM3_MEMORYMAP_H
#define LIBOPENCM3_MEMORYMAP_H
-
#include
/* Memory map for all buses */
+/** @defgroup memory_map Memory Map for All Buses
+@{*/
#define PERIPH_BASE (0x40000000U)
#define SYSTEM_CON_BASE (PERIPH_BASE + 0x0)
@@ -31,5 +40,7 @@
#define TIMER_SE1_BASE (PERIPH_BASE + 0x2400)
#define WDT_BASE (PERIPH_BASE + 0x19000)
#define SYSCTL_BASE (PERIPH_BASE + 0xf0000)
+/*@}*/
#endif
+/**@}*/
diff --git a/include/libopencm3/swm050/pwr.h b/include/libopencm3/swm050/pwr.h
new file mode 100644
index 00000000..0a135daa
--- /dev/null
+++ b/include/libopencm3/swm050/pwr.h
@@ -0,0 +1,40 @@
+/** @defgroup pwr_defines Power/Sleep Defines
+ *
+ * @brief Defined Constants and Types for the SWM050 Power/Sleep API
+ *
+ * @ingroup SWM050_defines
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2019 Caleb Szalacinski
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+/**@{*/
+#ifndef LIBOPENCM3_PWR_H
+#define LIBOPENCM3_PWR_H
+#include
+#include
+
+BEGIN_DECLS
+
+void pwr_sleep(void);
+
+END_DECLS
+
+#endif
+/**@}*/
diff --git a/include/libopencm3/swm050/syscon.h b/include/libopencm3/swm050/syscon.h
new file mode 100644
index 00000000..a9276dde
--- /dev/null
+++ b/include/libopencm3/swm050/syscon.h
@@ -0,0 +1,57 @@
+/** @defgroup syscon_defines SYSCON Defines
+ *
+ * @brief Defined Constants and Types for the SWM050 SYSCON peripheral
+ *
+ * @ingroup SWM050_defines
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2019 Icenowy Zheng
+ * Copyright (C) 2019 Caleb Szalacinski
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+/**@{*/
+#ifndef LIBOPENCM3_SYSCON_H
+#define LIBOPENCM3_SYSCON_H
+#include
+#include
+
+/* SYSCON Registers */
+/** @defgroup syscon_registers SYSCON Registers
+@{*/
+/** SWD Enable register */
+#define SYSCON_SWD_SEL MMIO32(SYSTEM_CON_BASE + 0x30)
+/** Pin Alternate function selection register */
+#define SYSCON_PORTA_SEL MMIO32(SYSTEM_CON_BASE + 0x80)
+/** Pin Pull up register */
+#define SYSCON_PORTA_PULLUP MMIO32(SYSTEM_CON_BASE + 0x90)
+/** Pin Input enable register */
+#define SYSCON_PORTA_INEN MMIO32(SYSTEM_CON_BASE + 0xe0)
+/*@}*/
+
+BEGIN_DECLS
+
+void syscon_sel_af(uint16_t gpios, bool af_en);
+void syscon_pullup(uint16_t gpios, bool en);
+void syscon_input_enable(uint16_t gpios, bool en);
+void syscon_sel_swd(bool en);
+
+END_DECLS
+
+#endif
+/**@}*/
diff --git a/include/libopencm3/swm050/sysctl.h b/include/libopencm3/swm050/sysctl.h
new file mode 100644
index 00000000..6fa642d0
--- /dev/null
+++ b/include/libopencm3/swm050/sysctl.h
@@ -0,0 +1,50 @@
+/** @defgroup sysctl_defines SYSCTL Defines
+ *
+ * @brief Defined Constants and Types for the SWM050 SYSCTL Registers
+ *
+ * @ingroup SWM050_defines
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2019 Caleb Szalacinski
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+/**@{*/
+#ifndef LIBOPENCM3_SYSCTL_H
+#define LIBOPENCM3_SYSCTL_H
+#include
+#include
+
+/** @defgroup sysctl_register SYSCTL Registers
+ * @note System configuration registers
+ * @{*/
+/** Clock dividers for TIMERSE and SCLK */
+#define SYSCTL_SYS_CFG_0 MMIO32(SYSCTL_BASE + 0x0)
+/** TIMERSE0, TIMERSE1, and WDT enable */
+#define SYSCTL_SYS_CFG_1 MMIO32(SYSCTL_BASE + 0x4)
+/** SCLK multiplier (18Mhz and 36Mhz) */
+#define SYSCTL_SYS_DBLF MMIO32(SYSCTL_BASE + 0x8)
+/** MOS Disconnect (Synwit says that this subregister is unused), Sleep Mode,
+ and Internal Oscillator Disconnect. Oscillator Disconnect should probably
+ not be used on the SWM050, because it has no external oscillator support */
+#define SYSCTL_SYS_CFG_2 MMIO32(SYSCTL_BASE + 0xC)
+/*@}*/
+
+#endif
+/**@}*/
diff --git a/ld/devices.data b/ld/devices.data
index 72f8cebd..3a2d9b0c 100644
--- a/ld/devices.data
+++ b/ld/devices.data
@@ -454,6 +454,11 @@ rm46l852* rm46l ROM=1280K RAM=192K
vf610 vf6xx RAM=256K RAM1=256K RAM_OFF=0x1f000000 RAM1_OFF=0x3f040000
+################################################################################
+# SWM050 chips
+
+swm050* END ROM=8K RAM=1K ROM_OFF=0x00000000 RAM_OFF=0x20000000 CPU=cortex-m0 FPU=soft
+
################################################################################
################################################################################
################################################################################
diff --git a/lib/swm050/Makefile b/lib/swm050/Makefile
index 977f5f74..10f03e6a 100644
--- a/lib/swm050/Makefile
+++ b/lib/swm050/Makefile
@@ -33,8 +33,11 @@ TGT_CFLAGS += $(DEBUG_FLAGS)
TGT_CFLAGS += $(STANDARD_FLAGS)
ARFLAGS = rcs
+OBJS += clk.o
+OBJS += flash.o
OBJS += gpio.o
-
+OBJS += pwr.o
+OBJS += syscon.o
VPATH += ../cm3
include ../Makefile.include
diff --git a/lib/swm050/clk.c b/lib/swm050/clk.c
new file mode 100644
index 00000000..a0ea1504
--- /dev/null
+++ b/lib/swm050/clk.c
@@ -0,0 +1,84 @@
+/** @addtogroup clk_file Clock peripheral API
+ * @ingroup peripheral_apis
+ * LGPL License Terms @ref lgpl_license
+ * @author @htmlonly © @endhtmlonly 2019
+ * Caleb Szalacinski
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2019 Caleb Szalacinski
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+/**@{*/
+#include
+#include
+
+/*---------------------------------------------------------------------------*/
+/** @brief Setup and change the system clock multiplier and divider
+
+Change system clock speed and wait for the clock to stabilize. The clock only
+needs time to stabilize on the first invocation of this function. This should be
+run at startup if you want to have a stable clock before doing anything.
+
+@param[in] mhz Base clock speed @ref clk_speeds
+ The base clock speed, before the clock divider
+
+@param[in] div Clock divider
+ Takes values from 0 to 1023 (in reality the possible values are the even
+ numbers from 2 to 1022, as well as the number 1). Anything more than the
+ first 10 bits is stripped off of the value. If the value is 0, it will
+ be treated as a 1. All odd values other than 1 are rounded down to the
+ closest even value, due to the fact that all odd values are treated by
+ the register as a 1, which would likely be unexpected. A value of 0
+ would also normally be treated as a 2, which would also be unexpected
+ behavior.
+*/
+void clk_speed(enum clk_speeds mhz, uint16_t div)
+{
+ static bool first_run = true;
+
+ if (first_run) {
+ first_run = false;
+ clk_speed(CLK_18MHZ, 1);
+
+ for (uint16_t i = 0; i < 10000; ++i) {
+ __asm__("nop");
+ }
+
+ /* The speed doesn't need to be changed
+ a second time if the user wants 18Mhz. */
+ if ((mhz == CLK_18MHZ) && (div <= 1)) {
+ return;
+ }
+ if ((mhz == CLK_36MHZ) && (div == 2)) {
+ return;
+ }
+ }
+
+ if (mhz == CLK_36MHZ) {
+ SYSCTL_SYS_DBLF |= BIT0;
+ } else {
+ SYSCTL_SYS_DBLF &= ~BIT0;
+ }
+
+ if (div <= 1) {
+ SYSCTL_SYS_CFG_0 |= BIT0;
+ } else {
+ uint32_t masked_reg32 = SYSCTL_SYS_CFG_0 & CLK_MASK;
+ SYSCTL_SYS_CFG_0 = masked_reg32 | (div & ~(CLK_MASK | 0x1));
+ }
+}
+/**@}*/
diff --git a/lib/swm050/flash.c b/lib/swm050/flash.c
new file mode 100644
index 00000000..79ff3f49
--- /dev/null
+++ b/lib/swm050/flash.c
@@ -0,0 +1,96 @@
+/** @addtogroup flash_file Flash peripheral API
+ * @ingroup peripheral_apis
+ * LGPL License Terms @ref lgpl_license
+ * @author @htmlonly © @endhtmlonly 2019
+ * Caleb Szalacinski
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2019 Caleb Szalacinski
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+/**@{*/
+#include
+
+/* Internal function pointers to the ROM flash API */
+#define IAP_WR (void *)(0x1000AB)
+#define IAP_E (void *)(0x100127)
+
+uint32_t (*iap_write_read)(uint32_t *, uint32_t *, uint8_t, uint8_t) = IAP_WR;
+uint32_t (*iap_erase)(void) = IAP_E;
+
+/*---------------------------------------------------------------------------*/
+/** @brief Write to the user flash
+
+Writes words to the 0.5k user flash area.
+Must be performed only when the system clock is 18Mhz.
+
+@param[in] dest Destination address
+ The memory area to copy to.
+ From 0x00 - 0x1FC, as long as it is word-aligned
+
+@param[in] src Source address
+ The memory area to copy from.
+
+@param[in] cnt Number of words to write
+ From 1-128 as long as (dest + (cnt * 4)) < 0x200
+
+@return 1 if successful, 0 if error
+
+*/
+uint32_t flash_write(uint32_t *dest, uint32_t *src, uint8_t cnt)
+{
+ return iap_write_read(dest, src, cnt, 1);
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Read from the user flash
+
+Reads words from the 0.5k user flash area.
+Must be performed only when the system clock is 18Mhz.
+
+@param[in] src Source address
+ The memory area to copy from.
+ From 0x00 - 0x1FC, as long as it is word-aligned
+
+@param[out] dest Destination address
+ The memory area to copy to.
+
+@param[in] cnt Number of words to read
+ From 1 - 128 as long as (src + (cnt * 4)) < 0x200
+
+@return 1 if successful, 0 if error
+
+*/
+uint32_t flash_read(uint32_t *src, uint32_t *dest, uint8_t cnt)
+{
+ return iap_write_read(src, dest, cnt, 0);
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Erase the user flash
+
+Erases the entire 0.5k user flash area.
+Must be performed only when the system clock is 18Mhz.
+
+@return 1 if successful, 0 if error
+
+*/
+uint32_t flash_erase(void)
+{
+ return iap_erase();
+}
+/**@}*/
diff --git a/lib/swm050/gpio.c b/lib/swm050/gpio.c
index fdf50996..2b78182f 100644
--- a/lib/swm050/gpio.c
+++ b/lib/swm050/gpio.c
@@ -1,10 +1,16 @@
/** @addtogroup gpio_file GPIO peripheral API
* @ingroup peripheral_apis
+ * LGPL License Terms @ref lgpl_license
+ * @author @htmlonly © @endhtmlonly 2019
+ * Icenowy Zheng
+ * @author @htmlonly © @endhtmlonly 2019
+ * Caleb Szalacinski
*/
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2019 Icenowy Zheng
+ * Copyright (C) 2019 Caleb Szalacinski
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -19,10 +25,8 @@
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see .
*/
-
-#include
-
/**@{*/
+#include
/*---------------------------------------------------------------------------*/
/** @brief Set a Group of Pins
@@ -36,7 +40,7 @@ atomic pin setting.
*/
void gpio_set(uint16_t gpios)
{
- GPIO_DATA |= gpios;
+ GPIO_ADATA |= gpios;
}
/*---------------------------------------------------------------------------*/
@@ -51,7 +55,7 @@ atomic pin setting.
*/
void gpio_clear(uint16_t gpios)
{
- GPIO_DATA &= ~gpios;
+ GPIO_ADATA &= ~gpios;
}
/*---------------------------------------------------------------------------*/
@@ -65,7 +69,7 @@ void gpio_clear(uint16_t gpios)
*/
uint16_t gpio_get(uint16_t gpios)
{
- return GPIO_EXT & gpios;
+ return GPIO_AEXT & gpios;
}
/*---------------------------------------------------------------------------*/
@@ -79,8 +83,8 @@ Toggle one or more pins of GPIO. The non-toggled pins are not affected.
*/
void gpio_toggle(uint16_t gpios)
{
- uint32_t curr_status = GPIO_DATA & gpios;
- GPIO_DATA = (GPIO_DATA & (~gpios)) | (~curr_status);
+ uint32_t curr_status = GPIO_ADATA & gpios;
+ GPIO_ADATA = (GPIO_ADATA & (~gpios)) | (~curr_status);
}
/*---------------------------------------------------------------------------*/
@@ -94,7 +98,7 @@ Set the direction of one or more pins of GPIO to input.
*/
void gpio_input(uint16_t gpios)
{
- GPIO_DIR &= ~gpios;
+ GPIO_ADIR &= ~gpios;
}
/*---------------------------------------------------------------------------*/
@@ -108,90 +112,142 @@ Set the direction of one or more pins of GPIO to output.
*/
void gpio_output(uint16_t gpios)
{
- GPIO_DIR |= gpios;
+ GPIO_ADIR |= gpios;
}
-/*---------------------------------------------------------------------------*/
-/** @brief Select the alternative function of a Group of Pins
-Select the alternative function of one or more pins of GPIO.
+/*---------------------------------------------------------------------------*/
+/** @brief Sets the pins as external interrupts, rather than normal GPIO
+
+Enable interrupts on the selected pins. If you want to quickly
+switch on and off interrupts, use gpio_int_mask() after calling this.
@param[in] gpios Pin identifiers @ref gpio_pin_id
If multiple pins are to be changed, use bitwise OR '|' to separate
them.
-@param[in] af_en Whether alternative function is selected
+
+@param[in] en True to enable, false to disable.
*/
-void gpio_sel_af(uint16_t gpios, bool af_en)
+void gpio_int_enable(uint16_t gpios, bool en)
{
- if (gpios & GPIO0) {
- GPIO_SEL = (GPIO_SEL & (~0x3)) | (af_en ? 0x1 : 0x0);
- }
- if (gpios & GPIO1) {
- GPIO_SEL = (GPIO_SEL & (~0xc)) | (af_en ? 0x4 : 0x0);
- }
- if (gpios & GPIO2) {
- GPIO_SEL = (GPIO_SEL & (~0x30)) | (af_en ? 0x10 : 0x0);
- }
- if (gpios & GPIO7) {
- GPIO_SEL = (GPIO_SEL & (~0xc000)) | (af_en ? 0x4000 : 0x0);
+ if (en) {
+ GPIO_INTEN_A |= gpios;
+ } else {
+ GPIO_INTEN_A &= ~gpios;
}
}
-/*---------------------------------------------------------------------------*/
-/** @brief Enable the internal pull-up of a Group of Pins
-Enable or disable the internal pull-up of one or more pins of GPIO.
+/*---------------------------------------------------------------------------*/
+/** @brief Sets bits in the interrupt mask
+
+When interrupts are masked, it prevents them from being received, which is a
+quicker way to turn on and off GPIO interrupts (after calling gpio_int_en()).
@param[in] gpios Pin identifiers @ref gpio_pin_id
If multiple pins are to be changed, use bitwise OR '|' to separate
them.
-@param[in] en Bool. Whether pull-up is enabled
+
+@param[in] masked Pin mask selection @ref gpio_int_masked
+ Whether to mask or unmask pins.
*/
-void gpio_pullup(uint16_t gpios, bool en)
+void gpio_int_mask(uint16_t gpios, enum gpio_int_masked masked)
{
- if (en) {
- GPIO_PULLUP |= gpios;
+ if (masked) {
+ GPIO_INTMASK_A |= gpios;
} else {
- GPIO_PULLUP &= ~gpios;
+ GPIO_INTMASK_A &= ~gpios;
}
}
-/*---------------------------------------------------------------------------*/
-/** @brief Enable the input function of a Group of Pins
-Enable or disable the input function of one or more pins of GPIO. Disabling
-the input function of pins decreases the power usage of the MCU.
+/*---------------------------------------------------------------------------*/
+/** @brief Sets whether the pins are edge triggered or level triggered
+
+Sets whether the pins are edge triggered or level triggered. Edge-triggered
+interrupt bits must be cleared by software.
@param[in] gpios Pin identifiers @ref gpio_pin_id
If multiple pins are to be changed, use bitwise OR '|' to separate
them.
-@param[in] en true to enable input function.
+
+@param[in] type Trigger Type @ref gpio_trig_type
+ Level or edge triggered
*/
-void gpio_in_en(uint16_t gpios, bool en)
+void gpio_int_type(uint16_t gpios, enum gpio_trig_type type)
{
- if (en) {
- GPIO_INEN &= ~gpios;
+ if (type) {
+ GPIO_INTLEVEL_A |= gpios;
} else {
- GPIO_INEN |= gpios;
+ GPIO_INTLEVEL_A &= ~gpios;
}
}
/*---------------------------------------------------------------------------*/
-/** @brief Select the SWD function of GPIO 1/2
+/** @brief Sets the interrupt trigger polarity
-Enable or disable the SWD debugging port at GPIO 1/2. When SWD debugging port
-is enabled, GPIO and AF of the SWD pins will be both unavailable.
+Sets whether the interrupt is triggered by a high or low level/edge.
-@param[in] en true to enable SWD.
+@param[in] gpios Pin identifiers @ref gpio_pin_id
+ If multiple pins are to be changed, use bitwise OR '|' to separate
+ them.
+
+@param[in] pol Polarity @ref gpio_pol
+ High or low level/edge
*/
-void gpio_sel_swd(bool en)
+void gpio_int_pol(uint16_t gpios, enum gpio_pol pol)
{
- if (en) {
- SWD_SEL = 1;
+ if (pol) {
+ GPIO_INTPOLARITY_A |= gpios;
} else {
- SWD_SEL = 0;
+ GPIO_INTPOLARITY_A &= ~gpios;
}
}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Gets the masked interrupt status
+
+Returns the pin interrupt status masked with the mask set
+in @ref gpio_int_mask().
+
+@return The masked pin interrupt status as a bitfield. The bit position of the
+ pin value returned corresponds to the pin number.
+*/
+uint16_t gpio_int_status(void)
+{
+ return GPIO_INTSTAT_A;
+}
+
+
+/*---------------------------------------------------------------------------*/
+/** @brief Gets the raw unmasked interrupt status
+
+Returns the raw unmasked interrupt status.
+
+@return The unmasked pin interrupt status as a bitfield. The bit position of the
+ pin value returned corresponds to the pin number.
+*/
+uint16_t gpio_int_raw_status(void)
+{
+ return GPIO_RAWINTSTAT_A;
+}
+
+
+/*---------------------------------------------------------------------------*/
+/** @brief Clear the specified pin interrupts
+
+Clears the specified pin interrupts. Edge-triggered interrupts must be cleared
+by software.
+
+@param[in] gpios Pin identifiers @ref gpio_pin_id
+ If multiple pins are to be changed, use bitwise OR '|' to separate
+ them.
+*/
+void gpio_int_clear(uint16_t gpios)
+{
+ GPIO_INTEOI_A |= gpios;
+}
+
/**@}*/
diff --git a/lib/swm050/pwr.c b/lib/swm050/pwr.c
new file mode 100644
index 00000000..904dbb2b
--- /dev/null
+++ b/lib/swm050/pwr.c
@@ -0,0 +1,41 @@
+/** @addtogroup pwr_file Power/Sleep API
+ * @ingroup peripheral_apis
+ * LGPL License Terms @ref lgpl_license
+ * @author @htmlonly © @endhtmlonly 2019
+ * Caleb Szalacinski
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2019 Caleb Szalacinski
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+/**@{*/
+#include
+#include
+
+/*---------------------------------------------------------------------------*/
+/** @brief Go into sleep mode
+
+Goes to sleep and wakes up on when GPIO pin 9 is pulled low. Please give
+yourself enough time to connect the debugger before calling this, in order to
+not get locked out of the MCU.
+
+*/
+void pwr_sleep(void)
+{
+ SYSCTL_SYS_CFG_2 |= (1<<4);
+}
+/**@}*/
diff --git a/lib/swm050/syscon.c b/lib/swm050/syscon.c
new file mode 100644
index 00000000..396f2ede
--- /dev/null
+++ b/lib/swm050/syscon.c
@@ -0,0 +1,115 @@
+/** @addtogroup syscon_file SYSCON peripheral API
+ * @ingroup peripheral_apis
+ * LGPL License Terms @ref lgpl_license
+ * @author @htmlonly © @endhtmlonly 2019
+ * Icenowy Zheng
+ * @author @htmlonly © @endhtmlonly 2019
+ * Caleb Szalacinski
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2019 Icenowy Zheng
+ * Copyright (C) 2019 Caleb Szalacinski
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+/**@{*/
+#include
+#include
+
+/*---------------------------------------------------------------------------*/
+/** @brief Select the alternative function of a Group of Pins
+
+Select the alternative function of one or more pins of GPIO.
+
+@param[in] gpios Pin identifiers @ref gpio_pin_id
+ If multiple pins are to be changed, use bitwise OR '|' to separate
+ them.
+@param[in] af_en Whether alternative function is selected
+*/
+void syscon_sel_af(uint16_t gpios, bool af_en)
+{
+ uint32_t masked_reg32;
+
+ if (gpios & GPIO0) {
+ masked_reg32 = SYSCON_PORTA_SEL & (~0x3);
+ SYSCON_PORTA_SEL = masked_reg32 | (af_en ? 0x1 : 0x0);
+ }
+ if (gpios & GPIO1) {
+ masked_reg32 = SYSCON_PORTA_SEL & (~0xc);
+ SYSCON_PORTA_SEL = masked_reg32 | (af_en ? 0x4 : 0x0);
+ }
+ if (gpios & GPIO2) {
+ masked_reg32 = SYSCON_PORTA_SEL & (~0x30);
+ SYSCON_PORTA_SEL = masked_reg32 | (af_en ? 0x10 : 0x0);
+ }
+ if (gpios & GPIO7) {
+ masked_reg32 = SYSCON_PORTA_SEL & (~0xc000);
+ SYSCON_PORTA_SEL = masked_reg32 | (af_en ? 0x4000 : 0x0);
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Enable the internal pull-up of a Group of Pins
+
+Enable or disable the internal pull-up of one or more pins of GPIO.
+
+@param[in] gpios Pin identifiers @ref gpio_pin_id
+ If multiple pins are to be changed, use bitwise OR '|' to separate
+ them.
+@param[in] en True to enable pull-up, false to disable.
+*/
+void syscon_pullup(uint16_t gpios, bool en)
+{
+ if (en) {
+ SYSCON_PORTA_PULLUP |= gpios;
+ } else {
+ SYSCON_PORTA_PULLUP &= ~gpios;
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Enable the input function of a Group of Pins
+
+Enable or disable the input function of one or more pins of GPIO. Disabling
+the input function of pins decreases the power usage of the MCU.
+
+@param[in] gpios Pin identifiers @ref gpio_pin_id
+ If multiple pins are to be changed, use bitwise OR '|' to separate
+ them.
+@param[in] en True to enable input function.
+*/
+void syscon_input_enable(uint16_t gpios, bool en)
+{
+ if (en) {
+ SYSCON_PORTA_INEN &= ~gpios;
+ } else {
+ SYSCON_PORTA_INEN |= gpios;
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Select the SWD function of GPIO 1/2
+
+Enable or disable the SWD debugging port at GPIO 1/2. When SWD debugging port
+is enabled, GPIO and AF of the SWD pins will be both unavailable.
+
+@param[in] en True to enable SWD.
+*/
+void syscon_sel_swd(bool en)
+{
+ SYSCON_SWD_SEL = en;
+}
+/**@}*/