1 /*******************************************************************************
\r
2 * (c) Copyright 2008-2013 Microsemi SoC Products Group. All rights reserved.
\r
4 * SmartFusion2 Microcontroller Subsystem GPIO bare metal software driver public
\r
7 * SVN $Revision: 5487 $
\r
8 * SVN $Date: 2013-03-29 15:33:22 +0000 (Fri, 29 Mar 2013) $
\r
11 /*=========================================================================*//**
\r
12 @mainpage SmartFusion2 MSS GPIO Bare Metal Driver.
\r
14 @section intro_sec Introduction
\r
15 The SmartFusion2 Microcontroller Subsystem (MSS) includes a block of 32 general
\r
16 purpose input/outputs (GPIO).
\r
17 This software driver provides a set of functions for controlling the MSS GPIO
\r
18 block as part of a bare metal system where no operating system is available.
\r
19 This driver can be adapted for use as part of an operating system but the
\r
20 implementation of the adaptation layer between this driver and the operating
\r
21 system's driver model is outside the scope of this driver.
\r
23 @section hw_dependencies Hardware Flow Dependencies
\r
24 The configuration of all features of the MSS GPIOs is covered by this driver
\r
25 with the exception of the SmartFusion2 IOMUX configuration. SmartFusion2
\r
26 allows multiple non-concurrent uses of some external pins through IOMUX
\r
27 configuration. This feature allows optimization of external pin usage by
\r
28 assigning external pins for use by either the microcontroller subsystem or the
\r
29 FPGA fabric. The MSS GPIOs share SmartFusion2 device external pins with the
\r
30 FPGA fabric and with other MSS peripherals via an IOMUX. The MSS GPIO ports
\r
31 can alternatively be routed to the FPGA fabric through an IOMUX.
\r
32 The IOMUXs are configured using the SmartFusion2 MSS configurator tool. You
\r
33 must ensure that the MSS GPIOs are enabled and configured in the SmartFusion2
\r
34 MSS configurator if you wish to use them. For more information on IOMUXs,
\r
35 refer to the IOMUX section of the SmartFusion2 Microcontroller Subsystem (MSS)
\r
37 The base address, register addresses and interrupt number assignment for the
\r
38 MSS GPIO block are defined as constants in the SmartFusion2 CMSIS HAL. You
\r
39 must ensure that the latest SmartFusion2 CMSIS HAL is included in the project
\r
40 settings of the software tool chain used to build your project and that it is
\r
41 generated into your project.
\r
43 @section theory_op Theory of Operation
\r
44 The MSS GPIO driver functions are grouped into the following categories:
\r
47 - Reading and setting GPIO state
\r
51 The MSS GPIO driver is initialized through a call to the MSS_GPIO_init()
\r
52 function. The MSS_GPIO_init() function must be called before any other MSS
\r
53 GPIO driver functions can be called.
\r
56 Each GPIO port is individually configured through a call to the
\r
57 MSS_GPIO_config() function. Configuration includes deciding if a GPIO port
\r
58 will be used as an input, an output or both. GPIO ports configured as inputs
\r
59 can be further configured to generate interrupts based on the input's state.
\r
60 Interrupts can be level or edge sensitive.
\r
62 Reading and Setting GPIO State
\r
63 The state of the GPIO ports can be read and set using the following functions:
\r
64 - MSS_GPIO_get_inputs()
\r
65 - MSS_GPIO_get_outputs()
\r
66 - MSS_GPIO_set_outputs()
\r
67 - MSS_GPIO_set_output()
\r
68 - MSS_GPIO_drive_inout()
\r
71 Interrupts generated by GPIO ports configured as inputs are controlled using
\r
72 the following functions:
\r
73 - MSS_GPIO_enable_irq()
\r
74 - MSS_GPIO_disable_irq()
\r
75 - MSS_GPIO_clear_irq()
\r
77 *//*=========================================================================*/
\r
85 #include "../../CMSIS/m2sxxx.h"
\r
87 /*-------------------------------------------------------------------------*//**
\r
88 The mss_gpio_id_t enumeration is used to identify individual GPIO ports as an
\r
89 argument to functions:
\r
91 - MSS_GPIO_set_output() and MSS_GPIO_drive_inout()
\r
92 - MSS_GPIO_enable_irq(), MSS_GPIO_disable_irq() and MSS_GPIO_clear_irq()
\r
94 typedef enum __mss_gpio_id_t
\r
130 /*-------------------------------------------------------------------------*//**
\r
131 These constant definitions are used as an argument to the
\r
132 MSS_GPIO_set_outputs() function to identify GPIO ports. A logical OR of these
\r
133 constants can be used to specify multiple GPIO ports.
\r
134 These definitions can also be used to identify GPIO ports through logical
\r
135 operations on the return value of the MSS_GPIO_get_inputs() function.
\r
137 #define MSS_GPIO_0_MASK 0x00000001uL
\r
138 #define MSS_GPIO_1_MASK 0x00000002uL
\r
139 #define MSS_GPIO_2_MASK 0x00000004uL
\r
140 #define MSS_GPIO_3_MASK 0x00000008uL
\r
141 #define MSS_GPIO_4_MASK 0x00000010uL
\r
142 #define MSS_GPIO_5_MASK 0x00000020uL
\r
143 #define MSS_GPIO_6_MASK 0x00000040uL
\r
144 #define MSS_GPIO_7_MASK 0x00000080uL
\r
145 #define MSS_GPIO_8_MASK 0x00000100uL
\r
146 #define MSS_GPIO_9_MASK 0x00000200uL
\r
147 #define MSS_GPIO_10_MASK 0x00000400uL
\r
148 #define MSS_GPIO_11_MASK 0x00000800uL
\r
149 #define MSS_GPIO_12_MASK 0x00001000uL
\r
150 #define MSS_GPIO_13_MASK 0x00002000uL
\r
151 #define MSS_GPIO_14_MASK 0x00004000uL
\r
152 #define MSS_GPIO_15_MASK 0x00008000uL
\r
153 #define MSS_GPIO_16_MASK 0x00010000uL
\r
154 #define MSS_GPIO_17_MASK 0x00020000uL
\r
155 #define MSS_GPIO_18_MASK 0x00040000uL
\r
156 #define MSS_GPIO_19_MASK 0x00080000uL
\r
157 #define MSS_GPIO_20_MASK 0x00100000uL
\r
158 #define MSS_GPIO_21_MASK 0x00200000uL
\r
159 #define MSS_GPIO_22_MASK 0x00400000uL
\r
160 #define MSS_GPIO_23_MASK 0x00800000uL
\r
161 #define MSS_GPIO_24_MASK 0x01000000uL
\r
162 #define MSS_GPIO_25_MASK 0x02000000uL
\r
163 #define MSS_GPIO_26_MASK 0x04000000uL
\r
164 #define MSS_GPIO_27_MASK 0x08000000uL
\r
165 #define MSS_GPIO_28_MASK 0x10000000uL
\r
166 #define MSS_GPIO_29_MASK 0x20000000uL
\r
167 #define MSS_GPIO_30_MASK 0x40000000uL
\r
168 #define MSS_GPIO_31_MASK 0x80000000uL
\r
170 /*-------------------------------------------------------------------------*//**
\r
171 These constant definitions are used as an argument to the MSS_GPIO_config()
\r
172 function to specify the I/O mode of each GPIO port.
\r
174 #define MSS_GPIO_INPUT_MODE 0x0000000002uL
\r
175 #define MSS_GPIO_OUTPUT_MODE 0x0000000005uL
\r
176 #define MSS_GPIO_INOUT_MODE 0x0000000003uL
\r
178 /*-------------------------------------------------------------------------*//**
\r
179 These constant definitions are used as an argument to the MSS_GPIO_config()
\r
180 function to specify the interrupt mode of each GPIO port.
\r
182 #define MSS_GPIO_IRQ_LEVEL_HIGH 0x0000000000uL
\r
183 #define MSS_GPIO_IRQ_LEVEL_LOW 0x0000000020uL
\r
184 #define MSS_GPIO_IRQ_EDGE_POSITIVE 0x0000000040uL
\r
185 #define MSS_GPIO_IRQ_EDGE_NEGATIVE 0x0000000060uL
\r
186 #define MSS_GPIO_IRQ_EDGE_BOTH 0x0000000080uL
\r
188 /*-------------------------------------------------------------------------*//**
\r
189 The mss_gpio_inout_state_t enumeration is used to specify the output state of
\r
190 an INOUT GPIO port as an argument to the MSS_GPIO_drive_inout() function.
\r
192 typedef enum mss_gpio_inout_state
\r
194 MSS_GPIO_DRIVE_LOW = 0,
\r
195 MSS_GPIO_DRIVE_HIGH,
\r
197 } mss_gpio_inout_state_t;
\r
199 /*-------------------------------------------------------------------------*//**
\r
200 The MSS_GPIO_init() function initializes the SmartFusion2 MSS GPIO block. It
\r
201 resets the MSS GPIO hardware block and it also clears any pending MSS GPIO
\r
202 interrupts in the ARM Cortex-M3 interrupt controller. When the function exits,
\r
203 it takes the MSS GPIO block out of reset.
\r
206 This function has no parameters.
\r
209 This function does not return a value.
\r
211 void MSS_GPIO_init( void );
\r
213 /*-------------------------------------------------------------------------*//**
\r
214 The MSS_GPIO_config() function is used to configure an individual GPIO port.
\r
217 The port_id parameter identifies the GPIO port to be configured. An
\r
218 enumeration item of the form MSS_GPIO_n, where n is the number of the GPIO
\r
219 port, is used to identify the GPIO port. For example, MSS_GPIO_0 identifies
\r
220 the first GPIO port and MSS_GPIO_31 is the last one.
\r
223 The config parameter specifies the configuration to be applied to the GPIO
\r
224 port identified by the port_id parameter. It is a logical OR of the required
\r
225 I/O mode and the required interrupt mode. The interrupt mode is not relevant
\r
226 if the GPIO is configured as an output only.
\r
227 These I/O mode constants are allowed:
\r
228 - MSS_GPIO_INPUT_MODE
\r
229 - MSS_GPIO_OUTPUT_MODE
\r
230 - MSS_GPIO_INOUT_MODE
\r
231 These interrupt mode constants are allowed:
\r
232 - MSS_GPIO_IRQ_LEVEL_HIGH
\r
233 - MSS_GPIO_IRQ_LEVEL_LOW
\r
234 - MSS_GPIO_IRQ_EDGE_POSITIVE
\r
235 - MSS_GPIO_IRQ_EDGE_NEGATIVE
\r
236 - MSS_GPIO_IRQ_EDGE_BOTH
\r
242 The following call will configure GPIO 4 as an input generating interrupts on
\r
243 a Low to High transition of the input:
\r
245 MSS_GPIO_config( MSS_GPIO_4, MSS_GPIO_INPUT_MODE | MSS_GPIO_IRQ_EDGE_POSITIVE );
\r
248 void MSS_GPIO_config
\r
250 mss_gpio_id_t port_id,
\r
254 /*-------------------------------------------------------------------------*//**
\r
255 The MSS_GPIO_set_outputs() function is used to set the state of all GPIO ports
\r
256 configured as outputs.
\r
259 The value parameter specifies the state of the GPIO ports configured as
\r
260 outputs. It is a bit mask of the form (MSS_GPIO_n_MASK | MSS_GPIO_m_MASK)
\r
261 where n and m are numbers identifying GPIOs. For example, (MSS_GPIO_0_MASK |
\r
262 MSS_GPIO_1_MASK | MSS_GPIO_2_MASK ) specifies that the first, second and
\r
263 third GPIO outputs must be set High and all other GPIO outputs set Low. The
\r
264 driver provides 32 mask constants, MSS_GPIO_0_MASK to MSS_GPIO_31_MASK
\r
265 inclusive, for this purpose.
\r
271 Set GPIOs outputs 0 and 8 high and all other GPIO outputs low.
\r
273 MSS_GPIO_set_outputs( MSS_GPIO_0_MASK | MSS_GPIO_8_MASK );
\r
277 Set GPIOs outputs 2 and 4 low without affecting other GPIO outputs.
\r
279 uint32_t gpio_outputs;
\r
280 gpio_outputs = MSS_GPIO_get_outputs();
\r
281 gpio_outputs &= ~( MSS_GPIO_2_MASK | MSS_GPIO_4_MASK );
\r
282 MSS_GPIO_set_outputs( gpio_outputs );
\r
285 @see MSS_GPIO_get_outputs()
\r
287 static __INLINE void
\r
288 MSS_GPIO_set_outputs
\r
293 GPIO->GPIO_OUT = value;
\r
296 /*-------------------------------------------------------------------------*//**
\r
297 The MSS_GPIO_set_output() function is used to set the state of a single GPIO
\r
298 port configured as an output.
\r
299 Note: Using bit-band writes might be a better option than this function for
\r
300 performance critical applications where the application code is not
\r
301 intended to be ported to a processor other than the ARM Cortex-M3 in
\r
302 SmartFusion2. The bit-band write equivalent to this function would be:
\r
303 GPIO_BITBAND->GPIO_OUT[port_id] = (uint32_t)value;
\r
306 The port_id parameter identifies the GPIO port that is to have its output
\r
307 set. An enumeration item of the form MSS_GPIO_n, where n is the number of
\r
308 the GPIO port, is used to identify the GPIO port. For example, MSS_GPIO_0
\r
309 identifies the first GPIO port and MSS_GPIO_31 is the last one.
\r
312 The value parameter specifies the desired state for the GPIO output. A value
\r
313 of 0 will set the output Low and a value of 1 will set the output High.
\r
316 This function does not return a value.
\r
319 The following call will set GPIO output 12 High, leaving all other GPIO
\r
320 outputs unaffected:
\r
322 _GPIO_set_output(MSS_GPIO_12, 1);
\r
325 void MSS_GPIO_set_output
\r
327 mss_gpio_id_t port_id,
\r
331 /*-------------------------------------------------------------------------*//**
\r
332 The MSS_GPIO_get_inputs() function is used to read the current state all GPIO
\r
333 ports configured as inputs.
\r
336 This function returns a 32-bit unsigned integer where each bit represents
\r
337 the state of a GPIO input. The least significant bit represents the state of
\r
338 GPIO input 0 and the most significant bit the state of GPIO input 31.
\r
341 Read and assign the current state of the GPIO outputs to a variable.
\r
343 uint32_t gpio_inputs;
\r
344 gpio_inputs = MSS_GPIO_get_inputs();
\r
347 static __INLINE uint32_t
\r
348 MSS_GPIO_get_inputs( void )
\r
350 return GPIO->GPIO_IN;
\r
353 /*-------------------------------------------------------------------------*//**
\r
354 The MSS_GPIO_get_outputs() function is used to read the current state all GPIO
\r
355 ports configured as outputs.
\r
358 This function returns a 32-bit unsigned integer where each bit represents
\r
359 the state of a GPIO output. The least significant bit represents the state
\r
360 of GPIO output 0 and the most significant bit the state of GPIO output 31.
\r
363 Read and assign the current state of the GPIO outputs to a variable.
\r
365 uint32_t gpio_outputs;
\r
366 gpio_outputs = MSS_GPIO_get_outputs();
\r
369 static __INLINE uint32_t
\r
370 MSS_GPIO_get_outputs( void )
\r
372 return GPIO->GPIO_OUT;
\r
375 /*-------------------------------------------------------------------------*//**
\r
376 The MSS_GPIO_drive_inout() function is used to set the output state of a
\r
377 single GPIO port configured as an INOUT. An INOUT GPIO can be in one of three
\r
382 An INOUT output would typically be used where several devices can drive the
\r
383 state of a shared signal line. The High and Low states are equivalent to the
\r
384 High and Low states of a GPIO configured as an output. The High impedance
\r
385 state is used to prevent the GPIO from driving its output state onto the
\r
386 signal line, while at the same time allowing the input state of the GPIO to
\r
390 The port_id parameter identifies the GPIO port for which you want to change
\r
391 the output state. An enumeration item of the form MSS_GPIO_n, where n is the
\r
392 number of the GPIO port, is used to identify the GPIO port. For example,
\r
393 MSS_GPIO_0 identifies the first GPIO port and MSS_GPIO_31 is the last one.
\r
396 The inout_state parameter specifies the state of the GPIO port identified by
\r
397 the port_id parameter. Allowed values of type mss_gpio_inout_state_t are as
\r
399 - MSS_GPIO_DRIVE_HIGH
\r
400 - MSS_GPIO_DRIVE_LOW
\r
401 - MSS_GPIO_HIGH_Z (High impedance)
\r
404 This function does not return a value.
\r
407 The call to MSS_GPIO_drive_inout() below will set the GPIO 7 output to the
\r
408 high impedance state.
\r
410 MSS_GPIO_drive_inout( MSS_GPIO_7, MSS_GPIO_HIGH_Z );
\r
413 void MSS_GPIO_drive_inout
\r
415 mss_gpio_id_t port_id,
\r
416 mss_gpio_inout_state_t inout_state
\r
419 /*-------------------------------------------------------------------------*//**
\r
420 The MSS_GPIO_enable_irq() function is used to enable interrupt generation for
\r
421 the specified GPIO input. Interrupts are generated based on the state of the
\r
422 GPIO input and the interrupt mode configured for it by MSS_GPIO_config().
\r
425 The port_id parameter identifies the GPIO port for which you want to enable
\r
426 interrupt generation. An enumeration item of the form MSS_GPIO_n, where n is
\r
427 the number of the GPIO port, is used to identify the GPIO port. For example,
\r
428 MSS_GPIO_0 identifies the first GPIO port and MSS_GPIO_31 is the last one.
\r
431 This function does not return a value.
\r
434 The call to MSS_GPIO_enable_irq() below will allow GPIO 8 to generate
\r
437 MSS_GPIO_enable_irq( MSS_GPIO_8 );
\r
440 void MSS_GPIO_enable_irq
\r
442 mss_gpio_id_t port_id
\r
445 /*-------------------------------------------------------------------------*//**
\r
446 The MSS_GPIO_disable_irq() function is used to disable interrupt generation
\r
447 for the specified GPIO input.
\r
450 The port_id parameter identifies the GPIO port for which you want to disable
\r
451 interrupt generation. An enumeration item of the form MSS_GPIO_n, where n is
\r
452 the number of the GPIO port, is used to identify the GPIO port. For example,
\r
453 MSS_GPIO_0 identifies the first GPIO port and MSS_GPIO_31 is the last one.
\r
456 This function does not return a value.
\r
459 The call to MSS_GPIO_disable_irq() below will prevent GPIO 8 from generating
\r
462 MSS_GPIO_disable_irq( MSS_GPIO_8 );
\r
465 void MSS_GPIO_disable_irq
\r
467 mss_gpio_id_t port_id
\r
470 /*-------------------------------------------------------------------------*//**
\r
471 The MSS_GPIO_clear_irq() function is used to clear a pending interrupt from
\r
472 the specified GPIO input.
\r
473 Note: The MSS_GPIO_clear_irq() function must be called as part of any GPIO
\r
474 interrupt service routine (ISR) in order to prevent the same interrupt
\r
475 event retriggering a call to the GPIO ISR.
\r
478 The port_id parameter identifies the GPIO port for which you want to clear
\r
479 the interrupt. An enumeration item of the form MSS_GPIO_n, where n is the
\r
480 number of the GPIO port, is used to identify the GPIO port. For example,
\r
481 MSS_GPIO_0 identifies the first GPIO port and MSS_GPIO_31 is the last one.
\r
487 The example below demonstrates the use of the MSS_GPIO_clear_irq() function
\r
488 as part of the GPIO 9 interrupt service routine.
\r
490 void GPIO9_IRQHandler( void )
\r
492 do_interrupt_processing();
\r
494 MSS_GPIO_clear_irq( MSS_GPIO_9 );
\r
498 void MSS_GPIO_clear_irq
\r
500 mss_gpio_id_t port_id
\r
507 #endif /* MSS_GPIO_H_ */
\r