summaryrefslogtreecommitdiff
path: root/FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole/polarfire_hal/platform/drivers/mss/mss_gpio/mss_gpio.h
diff options
context:
space:
mode:
Diffstat (limited to 'FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole/polarfire_hal/platform/drivers/mss/mss_gpio/mss_gpio.h')
-rw-r--r--FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole/polarfire_hal/platform/drivers/mss/mss_gpio/mss_gpio.h1071
1 files changed, 1071 insertions, 0 deletions
diff --git a/FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole/polarfire_hal/platform/drivers/mss/mss_gpio/mss_gpio.h b/FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole/polarfire_hal/platform/drivers/mss/mss_gpio/mss_gpio.h
new file mode 100644
index 000000000..7475d051f
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole/polarfire_hal/platform/drivers/mss/mss_gpio/mss_gpio.h
@@ -0,0 +1,1071 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ *
+ * PolarFire SoC Microprocessor Subsystem GPIO bare metal software driver
+ * public API.
+ *
+ * This driver is based on SmartFusion2 MSS GPIO driver v2.1.102
+ *
+ */
+
+/*=========================================================================*//**
+ @mainpage PolarFire SoC MSS GPIO Bare Metal Driver
+
+ ==============================================================================
+ Introduction
+ ==============================================================================
+ The PolarFire SoC Microprocessor Subsystem (MSS) includes three blocks of
+ general purpose input/outputs (GPIO). The GPIO0, GPIO1 and GPIO2 blocks have
+ 14, 24 and 32 GPIO ports respectively. This software driver provides a set of
+ functions for controlling the MSS GPIO blocks as part of a bare metal system
+ where no operating system is available. This driver can be adapted for use as
+ part of an operating system but the implementation of the adaptation layer
+ between this driver and the operating system's driver model is outside the
+ scope of this driver.
+
+ ==============================================================================
+ Hardware Flow Dependencies
+ ==============================================================================
+ The configuration of all features of the MSS GPIO peripherals is covered by
+ this driver with the exception of the PolarFire SoC IOMUX configuration.
+ PolarFire SoC allows multiple non-concurrent uses of some external pins
+ through IOMUX configuration. This feature allows optimization of external pin
+ usage by assigning external pins for use by either the microprocessor
+ subsystem or the FPGA fabric. The MSS GPIO signals are routed through
+ IOMUXs to the PolarFire SoC device external pins. The MSS GPIO serial
+ signals may also be routed through IOMUXs to the PolarFire SoC FPGA fabric.
+ For more information on IOMUX, refer to the IOMUX section of the PolarFire SoC
+ Microprocessor Subsystem (MSS) User's Guide.
+
+ The IOMUXs are configured using the PolarFire SoC MSS configurator tool. You
+ must ensure that the MSS GPIO peripherals are enabled and configured in the
+ PolarFire SoC MSS configurator if you wish to use them. For more information
+ on IOMUXs, refer to the IOMUX section of the PolarFire SoC microprocessor
+ Subsystem (MSS) User's Guide.
+
+ On PolarFire SoC an AXI switch forms a bus matrix interconnect among multiple
+ masters and multiple slaves. Five RISC-V CPUs connect to the Master ports
+ M10 to M14 of the AXI switch. By default, all the APB peripherals are
+ accessible on AXI-Slave 5 of the AXI switch via the AXI to AHB and AHB to APB
+ bridges (referred as main APB bus). However, to support logical separation in
+ the Asymmetric Multi-Processing (AMP) mode of operation, the APB peripherals
+ can alternatively be accessed on the AXI-Slave 6 via the AXI to AHB and AHB to
+ APB bridges (referred as the AMP APB bus).
+
+ Application must make sure that the desired GPIO instance is appropriately
+ configured on one of the APB bus described above by configuring the PolarFire
+ SoC system registers (SYSREG) as per the application need and that the
+ appropriate data structures are provided to this driver as parameter to the
+ functions provided by this driver.
+
+ The base address and register addresses are defined in this driver as
+ constants. The interrupt number assignment for the MSS GPIO peripherals are
+ defined as constants in the MPFS HAL. You must ensure that the latest MPFS HAL
+ is included in the project settings of the SoftConsole tool chain and that it
+ is generated into your project.
+
+ ==============================================================================
+ Theory of Operation
+ ==============================================================================
+ The MSS GPIO driver functions are grouped into the following categories:
+ - Initialization
+ - Configuration
+ - Reading and setting GPIO state
+ - Interrupt control
+
+ --------------------------------
+ Initialization
+ --------------------------------
+ The MSS GPIO driver is initialized through a call to the MSS_GPIO_init()
+ function. The MSS_GPIO_init() function must be called before any other MSS
+ GPIO driver functions can be called.
+
+ --------------------------------
+ Configuration
+ --------------------------------
+ Each GPIO port is individually configured through a call to the
+ MSS_GPIO_config() function. Configuration includes deciding if a GPIO port
+ will be used as an input, an output or both. GPIO ports configured as inputs
+ can be further configured to generate interrupts based on the input's state.
+ Interrupts can be level or edge sensitive. The MSS_GPIO_config_byte() function
+ can be used to configure eight consecutive GPIO ports identically. The
+ MSS_GPIO_config_byte() function can be used to configure all available GPIO
+ ports identically.
+
+ --------------------------------
+ Reading and Setting GPIO State
+ --------------------------------
+ The state of the GPIO ports can be read and set using the following functions:
+ - MSS_GPIO_get_inputs()
+ - MSS_GPIO_get_outputs()
+ - MSS_GPIO_set_outputs()
+ - MSS_GPIO_set_output()
+ - MSS_GPIO_drive_inout()
+
+ --------------------------------
+ Interrupt Control
+ --------------------------------
+ Interrupts generated by GPIO ports configured as inputs are controlled using
+ the following functions:
+ - MSS_GPIO_enable_irq()
+ - MSS_GPIO_disable_irq()
+ - MSS_GPIO_clear_irq()
+ - MSS_GPIO_get_irq()
+ - MSS_GPIO_enable_nondirect_irq()
+ - MSS_GPIO_disable_nondirect_irq()
+
+ The GPIO interrupts are multiplexed. Total GPIO interrupt inputs on PLIC are
+ 41.
+
+ 41 = (14 from GPIO0 + 24 from GPIO1 + 3 non direct interrupts)
+ GPIO2 interrupts are not available by default. Setting the corresponding bit
+ in GPIO_INTERRUPT_FAB_CR(31:0) system register will enable GPIO2(31:0)
+ corresponding interrupt on PLIC. e.g. If GPIO_INTERRUPT_FAB_CR bit0 is set
+ then GPIO2 bit0 interrupt is available on the direct input pin on the PLIC.
+ In this case GPIO0 bit 0 interrupt will not be available on the direct input
+ pin on the PLIC however, the GPIO0 non-direct input will be asserted as OR of
+ all the GPIO0 interrupts which don't have a direct interrupt input on PLIC are
+ connected to corresponding non-direct input pin. The table below explains all
+ the GPIO direct and non-direct interrupt connectivity options.
+
+ | PLIC | GPIO_INTERRUPT_FAB_CR = 0 | GPIO_INTERRUPT_FAB_CR = 1 |
+ |------|---------------------------|---------------------------|
+ | 0 | GPIO0 bit 0 | GPIO2 bit 0 |
+ | 1 | GPIO0 bit 1 | GPIO2 bit 1 |
+ | ... | ... | ... |
+ | 12 | GPIO0 bit 12 | GPIO2 bit 12 |
+ | 13 | GPIO0 bit 13 | GPIO2 bit 13 |
+ | 14 | GPIO1 bit 0 | GPIO2 bit 14 |
+ | 15 | GPIO1 bit 1 | GPIO2 bit 15 |
+ | ... | ... | ... |
+ | 30 | GPIO1 bit 16 | GPIO2 bit 30 |
+ | 31 | GPIO1 bit 17 | GPIO2 bit 31 |
+
+
+ | PLIC | Interrupt source |
+ |------|----------------------------------------------------------------------|
+ | 32 | GPIO1 bit 18 |
+ | 33 | GPIO1 bit 19 |
+ | 34 | GPIO1 bit 20 |
+ | 35 | GPIO1 bit 21 |
+ | 36 | GPIO1 bit 22 |
+ | 37 | GPIO1 bit 23 |
+ | 38 | OR of all GPIO0 interrupts who don't have a direct connection enabled|
+ | 39 | OR of all GPIO1 interrupts who don't have a direct connection enabled|
+ | 40 | OR of all GPIO2 interrupts who don't have a direct connection enabled|
+
+
+ NOTE: GPIO_INTERRUPT_FAB_CR controls the multiplexing in above table. It is
+ your responsibility to set up the GPIO_INTERRUPT_FAB_CR bits in application
+ code. you must make sure that you are using the valid combination of
+ GPIO0/1/2 interrupt per above table.
+
+ *//*=========================================================================*/
+#ifndef MSS_GPIO_H_
+#define MSS_GPIO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+/*-------------------------------------------------------------------------*//**
+ The mss_gpio_id_t enumeration is used to identify individual GPIO ports as an
+ argument to functions:
+ - MSS_GPIO_config()
+ - MSS_GPIO_set_output() and MSS_GPIO_drive_inout()
+ - MSS_GPIO_enable_irq(), MSS_GPIO_disable_irq() and MSS_GPIO_clear_irq()
+
+ Note that the GPIO0, GPIO1 and GPIO2 blocks have 14, 24 and 32 GPIO ports
+ respectively.
+ */
+typedef enum mss_gpio_id
+{
+ MSS_GPIO_0 = 0,
+ MSS_GPIO_1 = 1,
+ MSS_GPIO_2 = 2,
+ MSS_GPIO_3 = 3,
+ MSS_GPIO_4 = 4,
+ MSS_GPIO_5 = 5,
+ MSS_GPIO_6 = 6,
+ MSS_GPIO_7 = 7,
+ MSS_GPIO_8 = 8,
+ MSS_GPIO_9 = 9,
+ MSS_GPIO_10 = 10,
+ MSS_GPIO_11 = 11,
+ MSS_GPIO_12 = 12,
+ MSS_GPIO_13 = 13,
+ MSS_GPIO_14 = 14,
+ MSS_GPIO_15 = 15,
+ MSS_GPIO_16 = 16,
+ MSS_GPIO_17 = 17,
+ MSS_GPIO_18 = 18,
+ MSS_GPIO_19 = 19,
+ MSS_GPIO_20 = 20,
+ MSS_GPIO_21 = 21,
+ MSS_GPIO_22 = 22,
+ MSS_GPIO_23 = 23,
+ MSS_GPIO_24 = 24,
+ MSS_GPIO_25 = 25,
+ MSS_GPIO_26 = 26,
+ MSS_GPIO_27 = 27,
+ MSS_GPIO_28 = 28,
+ MSS_GPIO_29 = 29,
+ MSS_GPIO_30 = 30,
+ MSS_GPIO_31 = 31
+} mss_gpio_id_t;
+
+/*-------------------------------------------------------------------------*//**
+ The mss_gpio_inout_state_t enumeration is used to specify the output state of
+ an INOUT GPIO port as an argument to the MSS_GPIO_drive_inout() function.
+ */
+typedef enum mss_gpio_inout_state
+{
+ MSS_GPIO_DRIVE_LOW = 0,
+ MSS_GPIO_DRIVE_HIGH,
+ MSS_GPIO_HIGH_Z
+} mss_gpio_inout_state_t;
+
+/*-------------------------------------------------------------------------*//**
+ The mss_gpio_byte_num_t enumeration is used to specify the set of the 8
+ consecutive GPIO ports that are to be configured as an argument to the
+ MSS_GPIO_config_byte() function.
+ */
+typedef enum mss_gpio_byte_num
+{
+ MSS_GPIO_BYTE_0 = 0,
+ MSS_GPIO_BYTE_1,
+ MSS_GPIO_BYTE_2,
+ MSS_GPIO_BYTE_3,
+ MSS_GPIO_BYTE_INVALID,
+} mss_gpio_byte_num_t;
+
+/*-------------------------------------------------------------------------*//**
+ GPIO Instance Identification
+ ============================
+ These constants are provided for the application use. These constants must be
+ passed as a first parameter of all the APIs provided by this driver. The
+ GPIO0_LO, GPIO1_LO, GPIO2_LO represent the GPIO0, GPIO1 and GPIO2 hardware
+ blocks when they are connected on the main APB bus. The GPIO0_HI, GPIO1_HI,
+ GPIO2_HI represent the GPIO0, GPIO1 and GPIO2 hardware blocks when they are
+ connected on the AMP APB bus.
+
+ | Constant | Description |
+ |----------|---------------------------------------|
+ | GPIO0_LO | GPIO0 block connected on main APB bus |
+ | GPIO1_LO | GPIO1 block connected on main APB bus |
+ | GPIO2_LO | GPIO2 block connected on main APB bus |
+ | GPIO0_HI | GPIO0 block connected on AMP APB bus |
+ | GPIO1_HI | GPIO1 block connected on AMP APB bus |
+ | GPIO2_HI | GPIO2 block connected on AMP APB bus |
+
+ */
+#define GPIO0_LO ((GPIO_TypeDef*)0x20120000UL)
+#define GPIO1_LO ((GPIO_TypeDef*)0x20121000UL)
+#define GPIO2_LO ((GPIO_TypeDef*)0x20122000UL)
+#define GPIO0_HI ((GPIO_TypeDef*)0x28120000UL)
+#define GPIO1_HI ((GPIO_TypeDef*)0x28121000UL)
+#define GPIO2_HI ((GPIO_TypeDef*)0x28122000UL)
+
+/*-------------------------------------------------------------------------*//**
+ GPIO Port Masks
+ ===============
+ These constant definitions are used as an argument to the
+ MSS_GPIO_set_outputs() function to identify GPIO ports. A logical OR of these
+ constants can be used to specify multiple GPIO ports.
+ These definitions can also be used to identify GPIO ports through logical
+ operations on the return value of the MSS_GPIO_get_inputs() function.
+
+ | Constant | Description |
+ |------------------|-----------------------|
+ | MSS_GPIO_0_MASK | GPIO port 0-bit mask |
+ | MSS_GPIO_1_MASK | GPIO port 1-bit mask |
+ | MSS_GPIO_2_MASK | GPIO port 2-bit mask |
+ | MSS_GPIO_3_MASK | GPIO port 3-bit mask |
+ | MSS_GPIO_4_MASK | GPIO port 4-bit mask |
+ | MSS_GPIO_5_MASK | GPIO port 5-bit mask |
+ | MSS_GPIO_6_MASK | GPIO port 6-bit mask |
+ | MSS_GPIO_7_MASK | GPIO port 7-bit mask |
+ | MSS_GPIO_8_MASK | GPIO port 8-bit mask |
+ | MSS_GPIO_9_MASK | GPIO port 9-bit mask |
+ | MSS_GPIO_10_MASK | GPIO port 10-bit mask |
+ | MSS_GPIO_11_MASK | GPIO port 11-bit mask |
+ | MSS_GPIO_12_MASK | GPIO port 12-bit mask |
+ | MSS_GPIO_13_MASK | GPIO port 13-bit mask |
+ | MSS_GPIO_14_MASK | GPIO port 14-bit mask |
+ | MSS_GPIO_15_MASK | GPIO port 15-bit mask |
+ | MSS_GPIO_16_MASK | GPIO port 16-bit mask |
+ | MSS_GPIO_17_MASK | GPIO port 17-bit mask |
+ | MSS_GPIO_18_MASK | GPIO port 18-bit mask |
+ | MSS_GPIO_19_MASK | GPIO port 19-bit mask |
+ | MSS_GPIO_20_MASK | GPIO port 20-bit mask |
+ | MSS_GPIO_21_MASK | GPIO port 21-bit mask |
+ | MSS_GPIO_22_MASK | GPIO port 22-bit mask |
+ | MSS_GPIO_23_MASK | GPIO port 23-bit mask |
+ | MSS_GPIO_24_MASK | GPIO port 24-bit mask |
+ | MSS_GPIO_25_MASK | GPIO port 25-bit mask |
+ | MSS_GPIO_26_MASK | GPIO port 26-bit mask |
+ | MSS_GPIO_27_MASK | GPIO port 27-bit mask |
+ | MSS_GPIO_28_MASK | GPIO port 28-bit mask |
+ | MSS_GPIO_29_MASK | GPIO port 29-bit mask |
+ | MSS_GPIO_30_MASK | GPIO port 30-bit mask |
+ | MSS_GPIO_31_MASK | GPIO port 31-bit mask |
+
+ */
+#define MSS_GPIO_0_MASK 0x00000001UL
+#define MSS_GPIO_1_MASK 0x00000002UL
+#define MSS_GPIO_2_MASK 0x00000004UL
+#define MSS_GPIO_3_MASK 0x00000008UL
+#define MSS_GPIO_4_MASK 0x00000010UL
+#define MSS_GPIO_5_MASK 0x00000020UL
+#define MSS_GPIO_6_MASK 0x00000040UL
+#define MSS_GPIO_7_MASK 0x00000080UL
+#define MSS_GPIO_8_MASK 0x00000100UL
+#define MSS_GPIO_9_MASK 0x00000200UL
+#define MSS_GPIO_10_MASK 0x00000400UL
+#define MSS_GPIO_11_MASK 0x00000800UL
+#define MSS_GPIO_12_MASK 0x00001000UL
+#define MSS_GPIO_13_MASK 0x00002000UL
+#define MSS_GPIO_14_MASK 0x00004000UL
+#define MSS_GPIO_15_MASK 0x00008000UL
+#define MSS_GPIO_16_MASK 0x00010000UL
+#define MSS_GPIO_17_MASK 0x00020000UL
+#define MSS_GPIO_18_MASK 0x00040000UL
+#define MSS_GPIO_19_MASK 0x00080000UL
+#define MSS_GPIO_20_MASK 0x00100000UL
+#define MSS_GPIO_21_MASK 0x00200000UL
+#define MSS_GPIO_22_MASK 0x00400000UL
+#define MSS_GPIO_23_MASK 0x00800000UL
+#define MSS_GPIO_24_MASK 0x01000000UL
+#define MSS_GPIO_25_MASK 0x02000000UL
+#define MSS_GPIO_26_MASK 0x04000000UL
+#define MSS_GPIO_27_MASK 0x08000000UL
+#define MSS_GPIO_28_MASK 0x10000000UL
+#define MSS_GPIO_29_MASK 0x20000000UL
+#define MSS_GPIO_30_MASK 0x40000000UL
+#define MSS_GPIO_31_MASK 0x80000000UL
+
+/*-------------------------------------------------------------------------*//**
+ GPIO Port I/O Mode
+ ==================
+ These constant definitions are used as an argument to the MSS_GPIO_config()
+ function to specify the I/O mode of each GPIO port.
+
+ | Constant | Description |
+ |----------------------|----------------------------|
+ | MSS_GPIO_INPUT_MODE | Input port only |
+ | MSS_GPIO_OUTPUT_MODE | Output port only |
+ | MSS_GPIO_INOUT_MODE | Both input and output port |
+
+ */
+#define MSS_GPIO_INPUT_MODE 0x0000000002UL
+#define MSS_GPIO_OUTPUT_MODE 0x0000000005UL
+#define MSS_GPIO_INOUT_MODE 0x0000000003UL
+
+/*-------------------------------------------------------------------------*//**
+ GPIO Interrupt Mode
+ ===================
+ These constant definitions are used as an argument to the MSS_GPIO_config()
+ function to specify the interrupt mode of each GPIO port.
+
+ | Constant | Description |
+ |----------------------------|-----------------------------------------------------|
+ | MSS_GPIO_IRQ_LEVEL_HIGH | Interrupt on GPIO input level High |
+ | MSS_GPIO_IRQ_LEVEL_LOW | Interrupt on GPIO input level Low |
+ | MSS_GPIO_IRQ_EDGE_POSITIVE | Interrupt on GPIO input positive edge |
+ | MSS_GPIO_IRQ_EDGE_NEGATIVE | Interrupt on GPIO input negative edge |
+ | MSS_GPIO_IRQ_EDGE_BOTH | Interrupt on GPIO input positive and negative edges |
+
+ */
+#define MSS_GPIO_IRQ_LEVEL_HIGH 0x0000000000UL
+#define MSS_GPIO_IRQ_LEVEL_LOW 0x0000000020UL
+#define MSS_GPIO_IRQ_EDGE_POSITIVE 0x0000000040UL
+#define MSS_GPIO_IRQ_EDGE_NEGATIVE 0x0000000060UL
+#define MSS_GPIO_IRQ_EDGE_BOTH 0x0000000080UL
+
+/*------------------------Private data structures-----------------------------*/
+/*----------------------------------- GPIO -----------------------------------*/
+/*----------------------------------------------------------------------------*/
+typedef struct
+{
+ volatile uint32_t GPIO_CFG[32];
+ volatile uint32_t GPIO_IRQ;
+ volatile const uint32_t GPIO_IN;
+ volatile uint32_t GPIO_OUT;
+ volatile uint32_t GPIO_CFG_ALL;
+ volatile uint32_t GPIO_CFG_BYTE[4];
+ volatile uint32_t GPIO_CLR_BITS;
+ volatile uint32_t GPIO_SET_BITS;
+
+} GPIO_TypeDef;
+
+/*--------------------------------Public APIs---------------------------------*/
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_GPIO_init() function initializes the PolarFire SoC MSS GPIO block. It
+ resets the MSS GPIO hardware block and it also clears any pending MSS GPIO
+ interrupts in the interrupt controller. When the function exits,
+ it takes the MSS GPIO block out of reset.
+
+ @param gpio
+ The gpio parameter specifies the GPIO block that needs to be configured
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_gpio.h"
+ int main(void)
+ {
+ MSS_GPIO_init(GPIO0_LO);
+ MSS_GPIO_config(GPIO0_LO, MSS_GPIO_4, MSS_GPIO_INPUT_MODE |
+ MSS_GPIO_IRQ_EDGE_POSITIVE );
+ return (0u);
+ }
+ @endcode
+ */
+void MSS_GPIO_init
+(
+ GPIO_TypeDef * gpio
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_GPIO_config() function is used to configure an individual GPIO port.
+
+ @param gpio
+ The gpio parameter specifies the GPIO block that needs to be configured
+
+ @param port_id
+ The port_id parameter identifies the GPIO port to be configured. An
+ enumeration item of the form MSS_GPIO_n, where n is the number of the GPIO
+ port, is used to identify the GPIO port. For example, MSS_GPIO_0 identifies
+ the first GPIO port and MSS_GPIO_31 is the last one.
+
+ @param config
+ The config parameter specifies the configuration to be applied to the GPIO
+ port identified by the port_id parameter. It is a logical OR of the required
+ I/O mode and the required interrupt mode. The interrupt mode is not relevant
+ if the GPIO is configured as an output only.
+ These I/O mode constants are allowed:
+ - MSS_GPIO_INPUT_MODE
+ - MSS_GPIO_OUTPUT_MODE
+ - MSS_GPIO_INOUT_MODE
+ These interrupt mode constants are allowed:
+ - MSS_GPIO_IRQ_LEVEL_HIGH
+ - MSS_GPIO_IRQ_LEVEL_LOW
+ - MSS_GPIO_IRQ_EDGE_POSITIVE
+ - MSS_GPIO_IRQ_EDGE_NEGATIVE
+ - MSS_GPIO_IRQ_EDGE_BOTH
+
+ @return
+ This function does not return any value.
+
+ Example:
+ The following call will configure GPIO 4 on GPIO0 hardware block on main APB
+ bus as an input generating interrupts on a Low to High transition of the input
+ @code
+ #include "mss_gpio.h"
+ int main(void)
+ {
+ MSS_GPIO_init(GPIO0_LO);
+ MSS_GPIO_config(GPIO0_LO, MSS_GPIO_4, MSS_GPIO_INPUT_MODE |
+ MSS_GPIO_IRQ_EDGE_POSITIVE );
+ return (0u);
+ }
+ @endcode
+ */
+void MSS_GPIO_config
+(
+ GPIO_TypeDef * gpio,
+ mss_gpio_id_t port_id,
+ uint32_t config
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_GPIO_set_outputs() function is used to set the state of all GPIO ports
+ configured as outputs.
+
+ @param gpio
+ The gpio parameter specifies the GPIO block that needs to be configured
+
+ @param value
+ The value parameter specifies the state of the GPIO ports configured as
+ outputs. It is a bit mask of the form (MSS_GPIO_n_MASK | MSS_GPIO_m_MASK)
+ where n and m are numbers identifying GPIOs. For example, (MSS_GPIO_0_MASK |
+ MSS_GPIO_1_MASK | MSS_GPIO_2_MASK ) specifies that the first, second and
+ third GPIO outputs must be set High and all other GPIO outputs set Low. The
+ driver provides 32 mask constants, MSS_GPIO_0_MASK to MSS_GPIO_31_MASK
+ inclusive, for this purpose.
+
+ @return
+ This function does not return any value.
+
+ Example 1:
+ Set GPIOs outputs 0 and 8 high and all other GPIO outputs low.
+ @code
+ #include "mss_gpio.h"
+ int main(void)
+ {
+ MSS_GPIO_init(GPIO0_LO);
+ MSS_GPIO_config(GPIO0_LO, MSS_GPIO_4, MSS_GPIO_INPUT_MODE |
+ MSS_GPIO_IRQ_EDGE_POSITIVE );
+ MSS_GPIO_set_outputs(GPIO0_LO, MSS_GPIO_0_MASK | MSS_GPIO_8_MASK );
+ return (0u);
+ }
+
+ @endcode
+
+ Example 2:
+ Set GPIOs outputs 2 and 4 low without affecting other GPIO outputs.
+ @code
+ #include "mss_gpio.h"
+ int main(void)
+ {
+ uint32_t gpio_outputs;
+ MSS_GPIO_init(GPIO0_LO);
+ MSS_GPIO_config(GPIO0_LO, MSS_GPIO_4, MSS_GPIO_INPUT_MODE |
+ MSS_GPIO_IRQ_EDGE_POSITIVE );
+
+ gpio_outputs = MSS_GPIO_get_outputs();
+ gpio_outputs &= ~( MSS_GPIO_2_MASK | MSS_GPIO_4_MASK );
+ MSS_GPIO_set_outputs(GPIO0_LO, gpio_outputs );
+
+ return (0u);
+ }
+
+ @endcode
+
+ @see MSS_GPIO_get_outputs()
+ */
+static inline void
+MSS_GPIO_set_outputs
+(
+ GPIO_TypeDef * gpio,
+ uint32_t value
+)
+{
+ gpio->GPIO_OUT = value;
+}
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_GPIO_config_all() function is used to configure all the ports of the
+ GPIO block. This function will apply the same configuration values to all the
+ GPIO ports.
+
+ @param gpio
+ The gpio parameter specifies the GPIO block that needs to be configured
+
+ @param config
+ The config parameter specifies the configuration to be applied to the all
+ the GPIO ports. It is a logical OR of the required I/O mode and the required
+ interrupt mode. The interrupt mode is not relevant if the GPIO is configured
+ as an output only.
+ These I/O mode constants are allowed:
+ - MSS_GPIO_INPUT_MODE
+ - MSS_GPIO_OUTPUT_MODE
+ - MSS_GPIO_INOUT_MODE
+ These interrupt mode constants are allowed:
+ - MSS_GPIO_IRQ_LEVEL_HIGH
+ - MSS_GPIO_IRQ_LEVEL_LOW
+ - MSS_GPIO_IRQ_EDGE_POSITIVE
+ - MSS_GPIO_IRQ_EDGE_NEGATIVE
+ - MSS_GPIO_IRQ_EDGE_BOTH
+
+ @return
+ This function does not return any value.
+
+ Example:
+ @code
+ #include "mss_gpio.h"
+ int main(void)
+ {
+ MSS_GPIO_init(GPIO0_LO);
+ MSS_GPIO_config_all(GPIO0_LO, MSS_GPIO_INPUT_MODE |
+ MSS_GPIO_IRQ_EDGE_POSITIVE );
+ return (0u);
+ }
+ @endcode
+ */
+void MSS_GPIO_config_all
+(
+ GPIO_TypeDef * gpio,
+ uint32_t config
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_GPIO_config_byte() function is used to byte wise (consecutive 8 ports)
+ configure the gpio ports.
+
+ @param gpio
+ The gpio parameter specifies the GPIO block that needs to be configured.
+
+ @param byte_num
+ The byte_num parameter specifies the byte (consecutive 8 ports) which needs
+ to be configured. The value 0 indicates the bunch from gpio port0 to gpio
+ port7. Value of 3 indicates the bunch from gpio port25 to gpio port31.
+ When you use this function, you must make sure that the gpio ports that
+ you are trying to configure do exist for that GPIO hardware block.
+ GPIO0 has 14 ports.GPIO1 has 24 ports.GPIO3 has 32 ports.
+
+ @param config
+ The config parameter specifies the configuration to be applied to the GPIO
+ byte identified by the byte_num parameter. It is a logical OR of the
+ required I/O mode and the required interrupt mode. The interrupt mode is not
+ relevant if the GPIO is configured as an output only.
+ These I/O mode constants are allowed:
+ - MSS_GPIO_INPUT_MODE
+ - MSS_GPIO_OUTPUT_MODE
+ - MSS_GPIO_INOUT_MODE
+ These interrupt mode constants are allowed:
+ - MSS_GPIO_IRQ_LEVEL_HIGH
+ - MSS_GPIO_IRQ_LEVEL_LOW
+ - MSS_GPIO_IRQ_EDGE_POSITIVE
+ - MSS_GPIO_IRQ_EDGE_NEGATIVE
+ - MSS_GPIO_IRQ_EDGE_BOTH
+
+ @return
+ This function does not return any value.
+
+ Example:
+ @code
+ #include "mss_gpio.h"
+ int main(void)
+ {
+ MSS_GPIO_init(GPIO0_LO);
+ MSS_GPIO_config_byte(GPIO0_LO, MSS_GPIO_BYTE_1, MSS_GPIO_INPUT_MODE |
+ MSS_GPIO_IRQ_EDGE_POSITIVE );
+ return (0u);
+ }
+ @endcode
+ */
+void MSS_GPIO_config_byte
+(
+ GPIO_TypeDef * gpio,
+ mss_gpio_byte_num_t byte_num,
+ uint32_t config
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_GPIO_set_output() function is used to set the state of a single GPIO
+ port configured as an output.
+
+ @param gpio
+ The gpio parameter specifies the GPIO block that needs to be configured
+
+ @param port_id
+ The port_id parameter identifies the GPIO port that is to have its output
+ set. An enumeration item of the form MSS_GPIO_n, where n is the number of
+ the GPIO port, is used to identify the GPIO port. For example, MSS_GPIO_0
+ identifies the first GPIO port and MSS_GPIO_31 is the last one.
+
+ @param value
+ The value parameter specifies the desired state for the GPIO output. A value
+ of 0 will set the output Low and a value of 1 will set the output High.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ The following call will set GPIO output 12 High, leaving all other GPIO
+ outputs unaffected:
+ @code
+ #include "mss_gpio.h"
+ int main(void)
+ {
+ MSS_GPIO_init(GPIO0_LO);
+ MSS_GPIO_config_all(GPIO0_LO, MSS_GPIO_INOUT_MODE);
+ MSS_GPIO_set_output(GPIO0_LO, MSS_GPIO_13, 1);
+ return (0u);
+ }
+ @endcode
+ */
+void MSS_GPIO_set_output
+(
+ GPIO_TypeDef * gpio,
+ mss_gpio_id_t port_id,
+ uint8_t value
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_GPIO_get_inputs() function is used to read the current state all GPIO
+ ports configured as inputs.
+
+ @param gpio
+ The gpio parameter specifies the GPIO block that needs to be configured
+
+ @return
+ This function returns a 32-bit unsigned integer where each bit represents
+ the state of a GPIO input. The least significant bit represents the state of
+ GPIO input 0 and the most significant bit the state of GPIO input 31.
+
+ Example:
+ Read and assign the current state of the GPIO outputs to a variable.
+ @code
+ #include "mss_gpio.h"
+ int main(void)
+ {
+ uint32_t gpio_inputs;
+ MSS_GPIO_init(GPIO0_LO);
+ MSS_GPIO_config_all(GPIO0_LO, MSS_GPIO_INOUT_MODE);
+ gpio_inputs = MSS_GPIO_get_inputs(GPIO0_LO);
+ return (0u);
+ }
+ @endcode
+ */
+static inline uint32_t
+MSS_GPIO_get_inputs( GPIO_TypeDef const * gpio )
+{
+ return gpio->GPIO_IN;
+}
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_GPIO_enable_nondirect_irq() function is used to enable the non-direct
+ interrupt input at the PLIC.
+
+ @param gpio
+ The gpio parameter specifies the GPIO block that needs to be configured
+
+ @return
+ This function does not return any value.
+
+ Example:
+ Read and assign the current state of the GPIO outputs to a variable.
+ @code
+ #include "mss_gpio.h"
+ int main(void)
+ {
+ uint32_t gpio_inputs;
+ MSS_GPIO_init(GPIO0_LO);
+ MSS_GPIO_config_all(GPIO0_LO, MSS_GPIO_INOUT_MODE |
+ MSS_GPIO_IRQ_EDGE_POSITIVE);
+ MSS_GPIO_enable_nondirect_irq(GPIO1_LO);
+ return (0u);
+ }
+
+ @endcode
+ */
+void
+MSS_GPIO_enable_nondirect_irq
+(
+ GPIO_TypeDef const * gpio
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_GPIO_disable_nondirect_irq() function is used to disable the
+ non-direct interrupt input at the PLIC.
+
+ @param gpio
+ The gpio parameter specifies the GPIO block that needs to be configured
+
+ @return
+ This function does not return any value.
+
+ Example:
+ @code
+ #include "mss_gpio.h"
+ int main(void)
+ {
+ uint32_t gpio_inputs;
+ MSS_GPIO_init(GPIO0_LO);
+ MSS_GPIO_config_all(GPIO0_LO, MSS_GPIO_INOUT_MODE |
+ MSS_GPIO_IRQ_EDGE_POSITIVE);
+ MSS_GPIO_disable_nondirect_irq(GPIO1_LO);
+ return (0u);
+ }
+ @endcode
+ */
+void
+MSS_GPIO_disable_nondirect_irq
+(
+ GPIO_TypeDef const * gpio
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_GPIO_get_outputs() function is used to read the current state of all
+ GPIO ports configured as outputs.
+
+ @param gpio
+ The gpio parameter specifies the GPIO block that needs to be configured
+
+ @return
+ This function returns a 32-bit unsigned integer where each bit represents
+ the state of a GPIO output. The least significant bit represents the state
+ of GPIO output 0 and the most significant bit the state of GPIO output 31.
+
+ Example:
+ Read and assign the current state of the GPIO outputs to a variable.
+ @code
+ #include "mss_gpio.h"
+ int main(void)
+ {
+ uint32_t gpio_outputs;
+ MSS_GPIO_init(GPIO0_LO);
+ MSS_GPIO_config(GPIO0_LO, MSS_GPIO_4, MSS_GPIO_INPUT_MODE |
+ MSS_GPIO_IRQ_EDGE_POSITIVE );
+
+ gpio_outputs = MSS_GPIO_get_outputs();
+ gpio_outputs &= ~( MSS_GPIO_2_MASK | MSS_GPIO_4_MASK );
+ MSS_GPIO_set_outputs( gpio_outputs );
+
+ return (0u);
+ }
+ @endcode
+ */
+static inline uint32_t
+MSS_GPIO_get_outputs( GPIO_TypeDef const * gpio )
+{
+ return gpio->GPIO_OUT;
+}
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_GPIO_get_irq() function is used to read the current value of the IRQ
+ register. The GPIO interrupts are multiplexed. The GPIO interrupts which are
+ not available on the direct GPIO interrupt line on the PLIC are ORed and
+ routed to the non-direct interrupt line on the PLIC for the corresponding
+ GPIO hardware block. When the non-direct interrupt is asserted, this function
+ can be used to determine which exact GPIO bit(s) caused the interrupt.
+
+ @param gpio
+ The gpio parameter specifies the GPIO block that needs to be configured
+
+ @return
+ This function returns a 32-bit unsigned integer value of the IRQ register.
+
+ Example:
+ In the non-direct interrupt ISR, read the IRQ register to know which are
+ the GPIO port causing the interrupt.
+
+ @code
+ uint8_t gpio2_non_direct_plic_IRQHandler(void)
+ {
+ uint32_t intr_num = 0;
+ intr_num = MSS_GPIO_get_irq(GPIO2_LO);
+
+ for(int cnt=0; cnt<32; cnt++)
+ {
+ if (1u == (intr_num & 0x00000001U))
+ {
+ MSS_GPIO_clear_irq(GPIO0_LO, (mss_gpio_id_t)cnt);
+ }
+
+ intr_num >>= 1u;
+ }
+
+ return EXT_IRQ_KEEP_ENABLED;
+ }
+ @endcode
+ */
+static inline uint32_t
+MSS_GPIO_get_irq( GPIO_TypeDef const * gpio )
+{
+ return gpio->GPIO_IRQ;
+}
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_GPIO_drive_inout() function is used to set the output state of a
+ single GPIO port configured as an INOUT. An INOUT GPIO can be in one of three
+ states:
+ - High
+ - Low
+ - High impedance
+
+ An INOUT output would typically be used where several devices can drive the
+ state of a shared signal line. The High and Low states are equivalent to the
+ High and Low states of a GPIO configured as an output. The High impedance
+ state is used to prevent the GPIO from driving its output state onto the
+ signal line, while at the same time allowing the input state of the GPIO to
+ be read.
+
+ @param gpio
+ The gpio parameter specifies the GPIO block that needs to be configured
+
+ @param port_id
+ The port_id parameter identifies the GPIO port for which you want to change
+ the output state. An enumeration item of the form MSS_GPIO_n, where n is the
+ number of the GPIO port, is used to identify the GPIO port. For example,
+ MSS_GPIO_0 identifies the first GPIO port and MSS_GPIO_31 is the last one.
+
+ @param inout_state
+ The inout_state parameter specifies the state of the GPIO port identified by
+ the port_id parameter. Allowed values of type mss_gpio_inout_state_t are as
+ follows:
+ - MSS_GPIO_DRIVE_HIGH
+ - MSS_GPIO_DRIVE_LOW
+ - MSS_GPIO_HIGH_Z (High impedance)
+
+ @return
+ This function does not return a value.
+
+ Example:
+ The call to MSS_GPIO_drive_inout() below will set the GPIO 7 output to the
+ high impedance state.
+ @code
+ #include "mss_gpio.h"
+ int main(void)
+ {
+ uint32_t gpio_inputs;
+ MSS_GPIO_init(GPIO0_LO);
+ MSS_GPIO_config_all(GPIO0_LO, MSS_GPIO_INOUT_MODE |
+ MSS_GPIO_IRQ_EDGE_POSITIVE);
+ MSS_GPIO_drive_inout(GPIO0_LO, MSS_GPIO_7, MSS_GPIO_HIGH_Z);
+ return (0u);
+ }
+ @endcode
+ */
+void MSS_GPIO_drive_inout
+(
+ GPIO_TypeDef * gpio,
+ mss_gpio_id_t port_id,
+ mss_gpio_inout_state_t inout_state
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_GPIO_enable_irq() function is used to enable interrupt generation for
+ the specified GPIO input. Interrupts are generated based on the state of the
+ GPIO input and the interrupt mode configured for it by MSS_GPIO_config(). This
+ function enables the corresponding GPIO direct interrupt on the PLIC as well.
+
+ @param gpio
+ The gpio parameter specifies the GPIO block that needs to be configured
+
+ @param port_id
+ The port_id parameter identifies the GPIO port for which you want to enable
+ interrupt generation. An enumeration item of the form MSS_GPIO_n, where n is
+ the number of the GPIO port, is used to identify the GPIO port. For example,
+ MSS_GPIO_0 identifies the first GPIO port and MSS_GPIO_31 is the last one in
+ GPIO2 block.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ The call to MSS_GPIO_enable_irq() below will allow GPIO 8 to generate
+ interrupts.
+ @code
+ #include "mss_gpio.h"
+ int main(void)
+ {
+ uint32_t gpio_inputs;
+ MSS_GPIO_init(GPIO0_LO);
+ MSS_GPIO_config_all(GPIO0_LO, MSS_GPIO_INOUT_MODE |
+ MSS_GPIO_IRQ_EDGE_POSITIVE);
+ MSS_GPIO_enable_irq(GPIO0_LO, MSS_GPIO_8);
+ return (0u);
+ }
+
+ @endcode
+ */
+void MSS_GPIO_enable_irq
+(
+ GPIO_TypeDef * gpio,
+ mss_gpio_id_t port_id
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_GPIO_disable_irq() function is used to disable interrupt generation
+ for the specified GPIO input. This function disables the corresponding GPIO
+ direct interrupt on the PLIC as well.
+
+ @param gpio
+ The gpio parameter specifies the GPIO block that needs to be configured
+
+ @param port_id
+ The port_id parameter identifies the GPIO port for which you want to disable
+ interrupt generation. An enumeration item of the form MSS_GPIO_n, where n is
+ the number of the GPIO port, is used to identify the GPIO port. For example,
+ MSS_GPIO_0 identifies the first GPIO port and MSS_GPIO_31 is the last one.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ The call to MSS_GPIO_disable_irq() below will prevent GPIO 8 from generating
+ interrupts.
+ @code
+ MSS_GPIO_disable_irq( MSS_GPIO_8 );
+ @endcode
+ */
+void MSS_GPIO_disable_irq
+(
+ GPIO_TypeDef * gpio,
+ mss_gpio_id_t port_id
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_GPIO_clear_irq() function is used to clear a pending interrupt from
+ the specified GPIO input.
+
+ Note: The MSS_GPIO_clear_irq() function must be called as part of any GPIO
+ interrupt service routine (ISR) in order to prevent the same interrupt
+ event retriggering a call to the GPIO ISR.
+
+ @param gpio
+ The gpio parameter specifies the GPIO block that needs to be configured
+
+ @param port_id
+ The port_id parameter identifies the GPIO port for which you want to clear
+ the interrupt. An enumeration item of the form MSS_GPIO_n, where n is the
+ number of the GPIO port, is used to identify the GPIO port. For example,
+ MSS_GPIO_0 identifies the first GPIO port and MSS_GPIO_31 is the last one.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ The example below demonstrates the use of the MSS_GPIO_clear_irq() function
+ as part of the GPIO 9 interrupt service routine.
+
+ @code
+ uint8_t gpio2_non_direct_plic_IRQHandler(void)
+ {
+ uint32_t intr_num = 0;
+ intr_num = MSS_GPIO_get_irq(GPIO2_LO);
+
+ for(int cnt=0; cnt<32; cnt++)
+ {
+ if (1u == (intr_num & 0x00000001U))
+ {
+ MSS_GPIO_clear_irq(GPIO0_LO, (mss_gpio_id_t)cnt);
+ }
+
+ intr_num >>= 1u;
+ }
+
+ return EXT_IRQ_KEEP_ENABLED;
+ }
+ @endcode
+ */
+void MSS_GPIO_clear_irq
+(
+ GPIO_TypeDef * gpio,
+ mss_gpio_id_t port_id
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_GPIO_H_ */