1 /*******************************************************************************
2 * (c) Copyright 2008-2015 Microsemi SoC Products Group. All rights reserved.
3 *
4 * SmartFusion2 Microcontroller Subsystem GPIO bare metal software driver public
5 * API.
6 *
7 * SVN $Revision: 7748 $
8 * SVN $Date: 2015-09-04 11:36:30 +0530 (Fri, 04 Sep 2015) $
9 */
10
11 /*=========================================================================*//**
12 @mainpage SmartFusion2 MSS GPIO Bare Metal Driver.
13
14 @section intro_sec Introduction
15 The SmartFusion2 Microcontroller Subsystem (MSS) includes a block of 32 general
16 purpose input/outputs (GPIO).
17 This software driver provides a set of functions for controlling the MSS GPIO
18 block as part of a bare metal system where no operating system is available.
19 This driver can be adapted for use as part of an operating system but the
20 implementation of the adaptation layer between this driver and the operating
21 system's driver model is outside the scope of this driver.
22
23 @section hw_dependencies Hardware Flow Dependencies
24 The configuration of all features of the MSS GPIOs is covered by this driver
25 with the exception of the SmartFusion2 IOMUX configuration. SmartFusion2
26 allows multiple non-concurrent uses of some external pins through IOMUX
27 configuration. This feature allows optimization of external pin usage by
28 assigning external pins for use by either the microcontroller subsystem or the
29 FPGA fabric. The MSS GPIOs share SmartFusion2 device external pins with the
30 FPGA fabric and with other MSS peripherals via an IOMUX. The MSS GPIO ports
31 can alternatively be routed to the FPGA fabric through an IOMUX.
32 The IOMUXs are configured using the SmartFusion2 MSS configurator tool. You
33 must ensure that the MSS GPIOs are enabled and configured in the SmartFusion2
34 MSS configurator if you wish to use them. For more information on IOMUXs,
35 refer to the IOMUX section of the SmartFusion2 Microcontroller Subsystem (MSS)
36 User’s Guide.
37 The base address, register addresses and interrupt number assignment for the
38 MSS GPIO block are defined as constants in the SmartFusion2 CMSIS HAL. You
39 must ensure that the latest SmartFusion2 CMSIS HAL is included in the project
40 settings of the software tool chain used to build your project and that it is
41 generated into your project.
42
43 @section theory_op Theory of Operation
44 The MSS GPIO driver functions are grouped into the following categories:
45 - Initialization
46 - Configuration
47 - Reading and setting GPIO state
48 - Interrupt control
49
50 Initialization
51 The MSS GPIO driver is initialized through a call to the MSS_GPIO_init()
52 function. The MSS_GPIO_init() function must be called before any other MSS
53 GPIO driver functions can be called.
54
55 Configuration
56 Each GPIO port is individually configured through a call to the
57 MSS_GPIO_config() function. Configuration includes deciding if a GPIO port
58 will be used as an input, an output or both. GPIO ports configured as inputs
59 can be further configured to generate interrupts based on the input's state.
60 Interrupts can be level or edge sensitive.
61
62 Reading and Setting GPIO State
63 The state of the GPIO ports can be read and set using the following functions:
64 - MSS_GPIO_get_inputs()
65 - MSS_GPIO_get_outputs()
66 - MSS_GPIO_set_outputs()
67 - MSS_GPIO_set_output()
68 - MSS_GPIO_drive_inout()
69
70 Interrupt Control
71 Interrupts generated by GPIO ports configured as inputs are controlled using
72 the following functions:
73 - MSS_GPIO_enable_irq()
74 - MSS_GPIO_disable_irq()
75 - MSS_GPIO_clear_irq()
76
77 *//*=========================================================================*/
78 #ifndef MSS_GPIO_H_
79 #define MSS_GPIO_H_
80
81 #ifdef __cplusplus
82 extern "C" {
83 #endif
84
85 #include "../../CMSIS/m2sxxx.h"
86
87 /*-------------------------------------------------------------------------*//**
88 The mss_gpio_id_t enumeration is used to identify individual GPIO ports as an
89 argument to functions:
90 - MSS_GPIO_config()
91 - MSS_GPIO_set_output() and MSS_GPIO_drive_inout()
92 - MSS_GPIO_enable_irq(), MSS_GPIO_disable_irq() and MSS_GPIO_clear_irq()
93 */
94 typedef enum __mss_gpio_id_t
95 {
96 MSS_GPIO_0 = 0,
97 MSS_GPIO_1 = 1,
98 MSS_GPIO_2 = 2,
99 MSS_GPIO_3 = 3,
100 MSS_GPIO_4 = 4,
101 MSS_GPIO_5 = 5,
102 MSS_GPIO_6 = 6,
103 MSS_GPIO_7 = 7,
104 MSS_GPIO_8 = 8,
105 MSS_GPIO_9 = 9,
106 MSS_GPIO_10 = 10,
107 MSS_GPIO_11 = 11,
108 MSS_GPIO_12 = 12,
109 MSS_GPIO_13 = 13,
110 MSS_GPIO_14 = 14,
111 MSS_GPIO_15 = 15,
112 MSS_GPIO_16 = 16,
113 MSS_GPIO_17 = 17,
114 MSS_GPIO_18 = 18,
115 MSS_GPIO_19 = 19,
116 MSS_GPIO_20 = 20,
117 MSS_GPIO_21 = 21,
118 MSS_GPIO_22 = 22,
119 MSS_GPIO_23 = 23,
120 MSS_GPIO_24 = 24,
121 MSS_GPIO_25 = 25,
122 MSS_GPIO_26 = 26,
123 MSS_GPIO_27 = 27,
124 MSS_GPIO_28 = 28,
125 MSS_GPIO_29 = 29,
126 MSS_GPIO_30 = 30,
127 MSS_GPIO_31 = 31
128 } mss_gpio_id_t;
129
130 /*-------------------------------------------------------------------------*//**
131 These constant definitions are used as an argument to the
132 MSS_GPIO_set_outputs() function to identify GPIO ports. A logical OR of these
133 constants can be used to specify multiple GPIO ports.
134 These definitions can also be used to identify GPIO ports through logical
135 operations on the return value of the MSS_GPIO_get_inputs() function.
136 */
137 #define MSS_GPIO_0_MASK 0x00000001uL
138 #define MSS_GPIO_1_MASK 0x00000002uL
139 #define MSS_GPIO_2_MASK 0x00000004uL
140 #define MSS_GPIO_3_MASK 0x00000008uL
141 #define MSS_GPIO_4_MASK 0x00000010uL
142 #define MSS_GPIO_5_MASK 0x00000020uL
143 #define MSS_GPIO_6_MASK 0x00000040uL
144 #define MSS_GPIO_7_MASK 0x00000080uL
145 #define MSS_GPIO_8_MASK 0x00000100uL
146 #define MSS_GPIO_9_MASK 0x00000200uL
147 #define MSS_GPIO_10_MASK 0x00000400uL
148 #define MSS_GPIO_11_MASK 0x00000800uL
149 #define MSS_GPIO_12_MASK 0x00001000uL
150 #define MSS_GPIO_13_MASK 0x00002000uL
151 #define MSS_GPIO_14_MASK 0x00004000uL
152 #define MSS_GPIO_15_MASK 0x00008000uL
153 #define MSS_GPIO_16_MASK 0x00010000uL
154 #define MSS_GPIO_17_MASK 0x00020000uL
155 #define MSS_GPIO_18_MASK 0x00040000uL
156 #define MSS_GPIO_19_MASK 0x00080000uL
157 #define MSS_GPIO_20_MASK 0x00100000uL
158 #define MSS_GPIO_21_MASK 0x00200000uL
159 #define MSS_GPIO_22_MASK 0x00400000uL
160 #define MSS_GPIO_23_MASK 0x00800000uL
161 #define MSS_GPIO_24_MASK 0x01000000uL
162 #define MSS_GPIO_25_MASK 0x02000000uL
163 #define MSS_GPIO_26_MASK 0x04000000uL
164 #define MSS_GPIO_27_MASK 0x08000000uL
165 #define MSS_GPIO_28_MASK 0x10000000uL
166 #define MSS_GPIO_29_MASK 0x20000000uL
167 #define MSS_GPIO_30_MASK 0x40000000uL
168 #define MSS_GPIO_31_MASK 0x80000000uL
169
170 /*-------------------------------------------------------------------------*//**
171 These constant definitions are used as an argument to the MSS_GPIO_config()
172 function to specify the I/O mode of each GPIO port.
173 */
174 #define MSS_GPIO_INPUT_MODE 0x0000000002uL
175 #define MSS_GPIO_OUTPUT_MODE 0x0000000005uL
176 #define MSS_GPIO_INOUT_MODE 0x0000000003uL
177
178 /*-------------------------------------------------------------------------*//**
179 These constant definitions are used as an argument to the MSS_GPIO_config()
180 function to specify the interrupt mode of each GPIO port.
181 */
182 #define MSS_GPIO_IRQ_LEVEL_HIGH 0x0000000000uL
183 #define MSS_GPIO_IRQ_LEVEL_LOW 0x0000000020uL
184 #define MSS_GPIO_IRQ_EDGE_POSITIVE 0x0000000040uL
185 #define MSS_GPIO_IRQ_EDGE_NEGATIVE 0x0000000060uL
186 #define MSS_GPIO_IRQ_EDGE_BOTH 0x0000000080uL
187
188 /*-------------------------------------------------------------------------*//**
189 The mss_gpio_inout_state_t enumeration is used to specify the output state of
190 an INOUT GPIO port as an argument to the MSS_GPIO_drive_inout() function.
191 */
192 typedef enum mss_gpio_inout_state
193 {
194 MSS_GPIO_DRIVE_LOW = 0,
195 MSS_GPIO_DRIVE_HIGH,
196 MSS_GPIO_HIGH_Z
197 } mss_gpio_inout_state_t;
198
199 /*-------------------------------------------------------------------------*//**
200 The MSS_GPIO_init() function initializes the SmartFusion2 MSS GPIO block. It
201 resets the MSS GPIO hardware block and it also clears any pending MSS GPIO
202 interrupts in the ARM Cortex-M3 interrupt controller. When the function exits,
203 it takes the MSS GPIO block out of reset.
204
205 @param
206 This function has no parameters.
207
208 @return
209 This function does not return a value.
210 */
211 void MSS_GPIO_init( void );
212
213 /*-------------------------------------------------------------------------*//**
214 The MSS_GPIO_config() function is used to configure an individual GPIO port.
215
216 @param port_id
217 The port_id parameter identifies the GPIO port to be configured. An
218 enumeration item of the form MSS_GPIO_n, where n is the number of the GPIO
219 port, is used to identify the GPIO port. For example, MSS_GPIO_0 identifies
220 the first GPIO port and MSS_GPIO_31 is the last one.
221
222 @param config
223 The config parameter specifies the configuration to be applied to the GPIO
224 port identified by the port_id parameter. It is a logical OR of the required
225 I/O mode and the required interrupt mode. The interrupt mode is not relevant
226 if the GPIO is configured as an output only.
227 These I/O mode constants are allowed:
228 - MSS_GPIO_INPUT_MODE
229 - MSS_GPIO_OUTPUT_MODE
230 - MSS_GPIO_INOUT_MODE
231 These interrupt mode constants are allowed:
232 - MSS_GPIO_IRQ_LEVEL_HIGH
233 - MSS_GPIO_IRQ_LEVEL_LOW
234 - MSS_GPIO_IRQ_EDGE_POSITIVE
235 - MSS_GPIO_IRQ_EDGE_NEGATIVE
236 - MSS_GPIO_IRQ_EDGE_BOTH
237
238 @return
239 none.
240
241 Example:
242 The following call will configure GPIO 4 as an input generating interrupts on
243 a Low to High transition of the input:
244 @code
245 MSS_GPIO_config( MSS_GPIO_4, MSS_GPIO_INPUT_MODE | MSS_GPIO_IRQ_EDGE_POSITIVE );
246 @endcode
247 */
248 void MSS_GPIO_config
249 (
250 mss_gpio_id_t port_id,
251 uint32_t config
252 );
253
254 /*-------------------------------------------------------------------------*//**
255 The MSS_GPIO_set_outputs() function is used to set the state of all GPIO ports
256 configured as outputs.
257
258 @param value
259 The value parameter specifies the state of the GPIO ports configured as
260 outputs. It is a bit mask of the form (MSS_GPIO_n_MASK | MSS_GPIO_m_MASK)
261 where n and m are numbers identifying GPIOs. For example, (MSS_GPIO_0_MASK |
262 MSS_GPIO_1_MASK | MSS_GPIO_2_MASK ) specifies that the first, second and
263 third GPIO outputs must be set High and all other GPIO outputs set Low. The
264 driver provides 32 mask constants, MSS_GPIO_0_MASK to MSS_GPIO_31_MASK
265 inclusive, for this purpose.
266
267 @return
268 none.
269
270 Example 1:
271 Set GPIOs outputs 0 and 8 high and all other GPIO outputs low.
272 @code
273 MSS_GPIO_set_outputs( MSS_GPIO_0_MASK | MSS_GPIO_8_MASK );
274 @endcode
275
276 Example 2:
277 Set GPIOs outputs 2 and 4 low without affecting other GPIO outputs.
278 @code
279 uint32_t gpio_outputs;
280 gpio_outputs = MSS_GPIO_get_outputs();
281 gpio_outputs &= ~( MSS_GPIO_2_MASK | MSS_GPIO_4_MASK );
282 MSS_GPIO_set_outputs( gpio_outputs );
283 @endcode
284
285 @see MSS_GPIO_get_outputs()
286 */
287 static __INLINE void
MSS_GPIO_set_outputs(uint32_t value)288 MSS_GPIO_set_outputs
289 (
290 uint32_t value
291 )
292 {
293 GPIO->GPIO_OUT = value;
294 }
295
296 /*-------------------------------------------------------------------------*//**
297 The MSS_GPIO_set_output() function is used to set the state of a single GPIO
298 port configured as an output.
299 Note: Using bit-band writes might be a better option than this function for
300 performance critical applications where the application code is not
301 intended to be ported to a processor other than the ARM Cortex-M3 in
302 SmartFusion2. The bit-band write equivalent to this function would be:
303 GPIO_BITBAND->GPIO_OUT[port_id] = (uint32_t)value;
304
305 @param port_id
306 The port_id parameter identifies the GPIO port that is to have its output
307 set. An enumeration item of the form MSS_GPIO_n, where n is the number of
308 the GPIO port, is used to identify the GPIO port. For example, MSS_GPIO_0
309 identifies the first GPIO port and MSS_GPIO_31 is the last one.
310
311 @param value
312 The value parameter specifies the desired state for the GPIO output. A value
313 of 0 will set the output Low and a value of 1 will set the output High.
314
315 @return
316 This function does not return a value.
317
318 Example:
319 The following call will set GPIO output 12 High, leaving all other GPIO
320 outputs unaffected:
321 @code
322 _GPIO_set_output(MSS_GPIO_12, 1);
323 @endcode
324 */
325 void MSS_GPIO_set_output
326 (
327 mss_gpio_id_t port_id,
328 uint8_t value
329 );
330
331 /*-------------------------------------------------------------------------*//**
332 The MSS_GPIO_get_inputs() function is used to read the current state all GPIO
333 ports configured as inputs.
334
335 @return
336 This function returns a 32-bit unsigned integer where each bit represents
337 the state of a GPIO input. The least significant bit represents the state of
338 GPIO input 0 and the most significant bit the state of GPIO input 31.
339
340 Example:
341 Read and assign the current state of the GPIO outputs to a variable.
342 @code
343 uint32_t gpio_inputs;
344 gpio_inputs = MSS_GPIO_get_inputs();
345 @endcode
346 */
347 static __INLINE uint32_t
MSS_GPIO_get_inputs(void)348 MSS_GPIO_get_inputs( void )
349 {
350 return GPIO->GPIO_IN;
351 }
352
353 /*-------------------------------------------------------------------------*//**
354 The MSS_GPIO_get_outputs() function is used to read the current state all GPIO
355 ports configured as outputs.
356
357 @return
358 This function returns a 32-bit unsigned integer where each bit represents
359 the state of a GPIO output. The least significant bit represents the state
360 of GPIO output 0 and the most significant bit the state of GPIO output 31.
361
362 Example:
363 Read and assign the current state of the GPIO outputs to a variable.
364 @code
365 uint32_t gpio_outputs;
366 gpio_outputs = MSS_GPIO_get_outputs();
367 @endcode
368 */
369 static __INLINE uint32_t
MSS_GPIO_get_outputs(void)370 MSS_GPIO_get_outputs( void )
371 {
372 return GPIO->GPIO_OUT;
373 }
374
375 /*-------------------------------------------------------------------------*//**
376 The MSS_GPIO_drive_inout() function is used to set the output state of a
377 single GPIO port configured as an INOUT. An INOUT GPIO can be in one of three
378 states:
379 - High
380 - Low
381 - High impedance
382 An INOUT output would typically be used where several devices can drive the
383 state of a shared signal line. The High and Low states are equivalent to the
384 High and Low states of a GPIO configured as an output. The High impedance
385 state is used to prevent the GPIO from driving its output state onto the
386 signal line, while at the same time allowing the input state of the GPIO to
387 be read.
388
389 @param port_id
390 The port_id parameter identifies the GPIO port for which you want to change
391 the output state. An enumeration item of the form MSS_GPIO_n, where n is the
392 number of the GPIO port, is used to identify the GPIO port. For example,
393 MSS_GPIO_0 identifies the first GPIO port and MSS_GPIO_31 is the last one.
394
395 @param inout_state
396 The inout_state parameter specifies the state of the GPIO port identified by
397 the port_id parameter. Allowed values of type mss_gpio_inout_state_t are as
398 follows:
399 - MSS_GPIO_DRIVE_HIGH
400 - MSS_GPIO_DRIVE_LOW
401 - MSS_GPIO_HIGH_Z (High impedance)
402
403 @return
404 This function does not return a value.
405
406 Example:
407 The call to MSS_GPIO_drive_inout() below will set the GPIO 7 output to the
408 high impedance state.
409 @code
410 MSS_GPIO_drive_inout( MSS_GPIO_7, MSS_GPIO_HIGH_Z );
411 @endcode
412 */
413 void MSS_GPIO_drive_inout
414 (
415 mss_gpio_id_t port_id,
416 mss_gpio_inout_state_t inout_state
417 );
418
419 /*-------------------------------------------------------------------------*//**
420 The MSS_GPIO_enable_irq() function is used to enable interrupt generation for
421 the specified GPIO input. Interrupts are generated based on the state of the
422 GPIO input and the interrupt mode configured for it by MSS_GPIO_config().
423
424 @param port_id
425 The port_id parameter identifies the GPIO port for which you want to enable
426 interrupt generation. An enumeration item of the form MSS_GPIO_n, where n is
427 the number of the GPIO port, is used to identify the GPIO port. For example,
428 MSS_GPIO_0 identifies the first GPIO port and MSS_GPIO_31 is the last one.
429
430 @return
431 This function does not return a value.
432
433 Example:
434 The call to MSS_GPIO_enable_irq() below will allow GPIO 8 to generate
435 interrupts.
436 @code
437 MSS_GPIO_enable_irq( MSS_GPIO_8 );
438 @endcode
439 */
440 void MSS_GPIO_enable_irq
441 (
442 mss_gpio_id_t port_id
443 );
444
445 /*-------------------------------------------------------------------------*//**
446 The MSS_GPIO_disable_irq() function is used to disable interrupt generation
447 for the specified GPIO input.
448
449 @param port_id
450 The port_id parameter identifies the GPIO port for which you want to disable
451 interrupt generation. An enumeration item of the form MSS_GPIO_n, where n is
452 the number of the GPIO port, is used to identify the GPIO port. For example,
453 MSS_GPIO_0 identifies the first GPIO port and MSS_GPIO_31 is the last one.
454
455 @return
456 This function does not return a value.
457
458 Example:
459 The call to MSS_GPIO_disable_irq() below will prevent GPIO 8 from generating
460 interrupts.
461 @code
462 MSS_GPIO_disable_irq( MSS_GPIO_8 );
463 @endcode
464 */
465 void MSS_GPIO_disable_irq
466 (
467 mss_gpio_id_t port_id
468 );
469
470 /*-------------------------------------------------------------------------*//**
471 The MSS_GPIO_clear_irq() function is used to clear a pending interrupt from
472 the specified GPIO input.
473 Note: The MSS_GPIO_clear_irq() function must be called as part of any GPIO
474 interrupt service routine (ISR) in order to prevent the same interrupt
475 event retriggering a call to the GPIO ISR.
476
477 @param port_id
478 The port_id parameter identifies the GPIO port for which you want to clear
479 the interrupt. An enumeration item of the form MSS_GPIO_n, where n is the
480 number of the GPIO port, is used to identify the GPIO port. For example,
481 MSS_GPIO_0 identifies the first GPIO port and MSS_GPIO_31 is the last one.
482
483 @return
484 none.
485
486 Example:
487 The example below demonstrates the use of the MSS_GPIO_clear_irq() function
488 as part of the GPIO 9 interrupt service routine.
489 @code
490 void GPIO9_IRQHandler( void )
491 {
492 do_interrupt_processing();
493
494 MSS_GPIO_clear_irq( MSS_GPIO_9 );
495 }
496 @endcode
497 */
498 void MSS_GPIO_clear_irq
499 (
500 mss_gpio_id_t port_id
501 );
502
503 #ifdef __cplusplus
504 }
505 #endif
506
507 #endif /* MSS_GPIO_H_ */
508