]> git.sur5r.net Git - freertos/blob
b3ecb867a51e136324e46c54ae268d2737e863d3
[freertos] /
1 /*******************************************************************************\r
2  * (c) Copyright 2008-2013 Microsemi SoC Products Group.  All rights reserved.\r
3  * \r
4  *  SmartFusion2 Microcontroller Subsystem GPIO bare metal software driver public\r
5  *  API.\r
6  *\r
7  * SVN $Revision: 5487 $\r
8  * SVN $Date: 2013-03-29 15:33:22 +0000 (Fri, 29 Mar 2013) $\r
9  */\r
10 \r
11 /*=========================================================================*//**\r
12   @mainpage SmartFusion2 MSS GPIO Bare Metal Driver.\r
13 \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
22   \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
36   User’s Guide.\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
42   \r
43   @section theory_op Theory of Operation\r
44   The MSS GPIO driver functions are grouped into the following categories:\r
45     - Initialization\r
46     - Configuration\r
47     - Reading and setting GPIO state\r
48     - Interrupt control\r
49     \r
50   Initialization\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
54   \r
55   Configuration\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
61   \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
69   \r
70   Interrupt Control\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
76   \r
77  *//*=========================================================================*/\r
78 #ifndef MSS_GPIO_H_\r
79 #define MSS_GPIO_H_\r
80 \r
81 #ifdef __cplusplus\r
82 extern "C" {\r
83 #endif \r
84 \r
85 #include "../../CMSIS/m2sxxx.h"\r
86 \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
90     - MSS_GPIO_config()\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
93  */\r
94 typedef enum __mss_gpio_id_t\r
95 {\r
96     MSS_GPIO_0 = 0,\r
97     MSS_GPIO_1 = 1,\r
98     MSS_GPIO_2 = 2,\r
99     MSS_GPIO_3 = 3,\r
100     MSS_GPIO_4 = 4,\r
101     MSS_GPIO_5 = 5,\r
102     MSS_GPIO_6 = 6,\r
103     MSS_GPIO_7 = 7,\r
104     MSS_GPIO_8 = 8,\r
105     MSS_GPIO_9 = 9,\r
106     MSS_GPIO_10 = 10,\r
107     MSS_GPIO_11 = 11,\r
108     MSS_GPIO_12 = 12,\r
109     MSS_GPIO_13 = 13,\r
110     MSS_GPIO_14 = 14,\r
111     MSS_GPIO_15 = 15,\r
112     MSS_GPIO_16 = 16,\r
113     MSS_GPIO_17 = 17,\r
114     MSS_GPIO_18 = 18,\r
115     MSS_GPIO_19 = 19,\r
116     MSS_GPIO_20 = 20,\r
117     MSS_GPIO_21 = 21,\r
118     MSS_GPIO_22 = 22,\r
119     MSS_GPIO_23 = 23,\r
120     MSS_GPIO_24 = 24,\r
121     MSS_GPIO_25 = 25,\r
122     MSS_GPIO_26 = 26,\r
123     MSS_GPIO_27 = 27,\r
124     MSS_GPIO_28 = 28,\r
125     MSS_GPIO_29 = 29,\r
126     MSS_GPIO_30 = 30,\r
127     MSS_GPIO_31 = 31\r
128 } mss_gpio_id_t;\r
129 \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
136  */\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
169 \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
173  */\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
177 \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
181  */\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
187 \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
191  */\r
192 typedef enum mss_gpio_inout_state\r
193 {\r
194     MSS_GPIO_DRIVE_LOW = 0,\r
195     MSS_GPIO_DRIVE_HIGH,\r
196     MSS_GPIO_HIGH_Z\r
197 } mss_gpio_inout_state_t;\r
198 \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
204   \r
205    @param\r
206     This function has no parameters.\r
207     \r
208    @return\r
209     This function does not return a value.\r
210  */\r
211 void MSS_GPIO_init( void );\r
212 \r
213 /*-------------------------------------------------------------------------*//**\r
214   The MSS_GPIO_config() function is used to configure an individual GPIO port.\r
215  \r
216   @param port_id\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
221     \r
222   @param config\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
237   \r
238    @return\r
239     none.\r
240 \r
241   Example:\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
244   @code\r
245   MSS_GPIO_config( MSS_GPIO_4, MSS_GPIO_INPUT_MODE | MSS_GPIO_IRQ_EDGE_POSITIVE );\r
246   @endcode\r
247  */\r
248 void MSS_GPIO_config\r
249 (\r
250     mss_gpio_id_t port_id,\r
251     uint32_t config\r
252 );\r
253 \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
257  \r
258   @param value\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
266   \r
267   @return\r
268     none.\r
269 \r
270   Example 1:\r
271     Set GPIOs outputs 0 and 8 high and all other GPIO outputs low.\r
272     @code\r
273         MSS_GPIO_set_outputs( MSS_GPIO_0_MASK | MSS_GPIO_8_MASK );\r
274     @endcode\r
275 \r
276   Example 2:\r
277     Set GPIOs outputs 2 and 4 low without affecting other GPIO outputs.\r
278     @code\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
283     @endcode\r
284 \r
285   @see MSS_GPIO_get_outputs()\r
286  */\r
287 static __INLINE void\r
288 MSS_GPIO_set_outputs\r
289 (\r
290    uint32_t value\r
291 )\r
292 {\r
293     GPIO->GPIO_OUT = value;\r
294 }\r
295 \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
304  \r
305   @param port_id\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
310   \r
311   @param value\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
314   \r
315   @return\r
316     This function does not return a value.\r
317     \r
318   Example:\r
319   The following call will set GPIO output 12 High, leaving all other GPIO\r
320   outputs unaffected:\r
321   @code\r
322     _GPIO_set_output(MSS_GPIO_12, 1);\r
323   @endcode\r
324  */\r
325 void MSS_GPIO_set_output\r
326 (\r
327     mss_gpio_id_t       port_id,\r
328     uint8_t             value\r
329 );\r
330 \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
334  \r
335   @return\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
339 \r
340   Example:\r
341     Read and assign the current state of the GPIO outputs to a variable.\r
342     @code\r
343         uint32_t gpio_inputs;\r
344         gpio_inputs = MSS_GPIO_get_inputs();\r
345     @endcode\r
346  */\r
347 static __INLINE uint32_t\r
348 MSS_GPIO_get_inputs( void )\r
349 {\r
350     return GPIO->GPIO_IN;\r
351 }\r
352 \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
356  \r
357   @return\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
361 \r
362   Example:\r
363     Read and assign the current state of the GPIO outputs to a variable.\r
364     @code\r
365         uint32_t gpio_outputs;\r
366         gpio_outputs = MSS_GPIO_get_outputs();\r
367     @endcode\r
368  */\r
369 static __INLINE uint32_t\r
370 MSS_GPIO_get_outputs( void )\r
371 {\r
372     return GPIO->GPIO_OUT;\r
373 }\r
374 \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
378   states:\r
379     - High\r
380     - Low\r
381     - High impedance\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
387   be read.\r
388   \r
389   @param port_id\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
394     \r
395   @param inout_state\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
398     follows:\r
399         - MSS_GPIO_DRIVE_HIGH\r
400         - MSS_GPIO_DRIVE_LOW\r
401         - MSS_GPIO_HIGH_Z  (High impedance)\r
402         \r
403   @return\r
404     This function does not return a value.\r
405 \r
406   Example:\r
407     The call to MSS_GPIO_drive_inout() below will set the GPIO 7 output to the\r
408     high impedance state.\r
409     @code\r
410     MSS_GPIO_drive_inout( MSS_GPIO_7, MSS_GPIO_HIGH_Z );\r
411     @endcode\r
412  */\r
413 void MSS_GPIO_drive_inout\r
414 (\r
415     mss_gpio_id_t           port_id,\r
416     mss_gpio_inout_state_t  inout_state\r
417 );\r
418 \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
423  \r
424   @param port_id\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
429     \r
430   @return\r
431     This function does not return a value.\r
432 \r
433   Example:\r
434     The call to MSS_GPIO_enable_irq() below will allow GPIO 8 to generate\r
435     interrupts.\r
436     @code\r
437     MSS_GPIO_enable_irq( MSS_GPIO_8 );\r
438     @endcode\r
439  */\r
440 void MSS_GPIO_enable_irq\r
441 (\r
442     mss_gpio_id_t port_id\r
443 );\r
444 \r
445 /*-------------------------------------------------------------------------*//**\r
446   The MSS_GPIO_disable_irq() function is used to disable interrupt generation\r
447   for the specified GPIO input.\r
448  \r
449   @param port_id\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
454  \r
455   @return\r
456     This function does not return a value.\r
457 \r
458   Example:\r
459     The call to MSS_GPIO_disable_irq() below will prevent GPIO 8 from generating\r
460     interrupts.\r
461     @code\r
462     MSS_GPIO_disable_irq( MSS_GPIO_8 );\r
463     @endcode\r
464  */\r
465 void MSS_GPIO_disable_irq\r
466 (\r
467     mss_gpio_id_t port_id\r
468 );\r
469 \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
476  \r
477   @param port_id\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
482     \r
483   @return\r
484     none.\r
485 \r
486   Example:\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
489     @code\r
490     void GPIO9_IRQHandler( void )\r
491     {\r
492         do_interrupt_processing();\r
493         \r
494         MSS_GPIO_clear_irq( MSS_GPIO_9 );\r
495     }\r
496     @endcode\r
497  */\r
498 void MSS_GPIO_clear_irq\r
499 (\r
500     mss_gpio_id_t port_id\r
501 );\r
502 \r
503 #ifdef __cplusplus\r
504 }\r
505 #endif\r
506 \r
507 #endif /* MSS_GPIO_H_ */\r