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; +} +/**@}*/