1 /*******************************************************************************
\r
2 * (c) Copyright 2008 Actel Corporation. All rights reserved.
\r
4 * SmartFusion Microcontroller Subsystem GPIO bare metal software driver public
\r
7 * SVN $Revision: 1751 $
\r
8 * SVN $Date: 2009-12-11 15:05:48 +0000 (Fri, 11 Dec 2009) $
\r
11 /*=========================================================================*//**
\r
12 @mainpage SmartFusion MSS GPIO Bare Metal Driver.
\r
14 @section intro_sec Introduction
\r
15 The SmartFusion 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 SmartFusion IOMUX configuration. SmartFusion allows
\r
26 multiple non-concurrent use of some external pins through IOMUX configuration.
\r
27 This feature allows optimizing external pin usage by assigning external pins
\r
28 for usage by either the microcontroller subsystem or the FPGA fabric.
\r
29 The MSS GPIO ports 0 to 15 are always connected to external pins but GPIO ports
\r
30 16 to 31 are routed through IOMUX to the SmartFusion device external pins.
\r
31 These IOMUX are configured using the MSS Configurator tool.
\r
32 Make sure the MSS GPIOs 16 to 31 are enabled in the MSS Configurator tool if
\r
33 you wish to use them
\r
35 @section theory_op Theory of Operation
\r
36 The MSS GPIO driver uses the SmartFusion "Cortex Microcontroler Software
\r
37 Interface Standard - Peripheral Access Layer" (CMSIS-PAL) to access MSS hardware
\r
38 registers. You must ensure that the SmartFusion CMSIS-PAL is either included
\r
39 in the software toolchain used to build your project or is included in your
\r
40 project. The most up-to-date SmartFusion CMSIS-PAL files can be obtained using
\r
41 the Actel Firmware Catalog.
\r
43 The MSS GPIO driver functions are grouped into the following categories:
\r
46 - Reading and setting GPIO state
\r
49 The MSS GPIO driver is initialized through a call to the GPIO_init() function.
\r
50 The GPIO_init() function must be called before any other GPIO driver functions
\r
53 Each GPIO port is individually configured through a call to the
\r
54 MSS_GPIO_config() function. Configuration includes deciding if a GPIO port
\r
55 will be used as an input, an output or both. GPIO ports configured as inputs can be
\r
56 further configured to generate interrupts based on the input's state.
\r
57 Interrupts can be level or edge sensitive.
\r
59 The state of the GPIO ports can be read and set using the following functions:
\r
60 - MSS_GPIO_get_inputs()
\r
61 - MSS_GPIO_get_outputs()
\r
62 - MSS_GPIO_set_outputs()
\r
63 - MSS_GPIO_set_output()
\r
64 - MSS_GPIO_drive_inout()
\r
66 Interrupts generated by GPIO ports configured as inputs are controlled using
\r
67 the following functions:
\r
68 - MSS_GPIO_enable_irq()
\r
69 - MSS_GPIO_disable_irq()
\r
70 - MSS_GPIO_clear_irq()
\r
72 *//*=========================================================================*/
\r
80 #include "../../CMSIS/a2fxxxm3.h"
\r
82 /*-------------------------------------------------------------------------*//**
\r
83 The mss_gpio_id_t enumeration is used to identify GPIOs as part of the
\r
84 parameter to functions:
\r
85 - MSS_GPIO_config(),
\r
86 - MSS_GPIO_drive_inout(),
\r
87 - MSS_GPIO_enable_irq(),
\r
88 - MSS_GPIO_disable_irq(),
\r
89 - MSS_GPIO_clear_irq()
\r
91 typedef enum __mss_gpio_id_t
\r
127 /*-------------------------------------------------------------------------*//**
\r
128 GPIO ports definitions used to identify GPIOs as part of the parameter to
\r
129 function MSS_GPIO_set_outputs().
\r
130 These definitions can also be used to identity GPIO through logical
\r
131 operations on the return value of function MSS_GPIO_get_inputs().
\r
133 #define MSS_GPIO_0_MASK 0x00000001UL
\r
134 #define MSS_GPIO_1_MASK 0x00000002UL
\r
135 #define MSS_GPIO_2_MASK 0x00000004UL
\r
136 #define MSS_GPIO_3_MASK 0x00000008UL
\r
137 #define MSS_GPIO_4_MASK 0x00000010UL
\r
138 #define MSS_GPIO_5_MASK 0x00000020UL
\r
139 #define MSS_GPIO_6_MASK 0x00000040UL
\r
140 #define MSS_GPIO_7_MASK 0x00000080UL
\r
141 #define MSS_GPIO_8_MASK 0x00000100UL
\r
142 #define MSS_GPIO_9_MASK 0x00000200UL
\r
143 #define MSS_GPIO_10_MASK 0x00000400UL
\r
144 #define MSS_GPIO_11_MASK 0x00000800UL
\r
145 #define MSS_GPIO_12_MASK 0x00001000UL
\r
146 #define MSS_GPIO_13_MASK 0x00002000UL
\r
147 #define MSS_GPIO_14_MASK 0x00004000UL
\r
148 #define MSS_GPIO_15_MASK 0x00008000UL
\r
149 #define MSS_GPIO_16_MASK 0x00010000UL
\r
150 #define MSS_GPIO_17_MASK 0x00020000UL
\r
151 #define MSS_GPIO_18_MASK 0x00040000UL
\r
152 #define MSS_GPIO_19_MASK 0x00080000UL
\r
153 #define MSS_GPIO_20_MASK 0x00100000UL
\r
154 #define MSS_GPIO_21_MASK 0x00200000UL
\r
155 #define MSS_GPIO_22_MASK 0x00400000UL
\r
156 #define MSS_GPIO_23_MASK 0x00800000UL
\r
157 #define MSS_GPIO_24_MASK 0x01000000UL
\r
158 #define MSS_GPIO_25_MASK 0x02000000UL
\r
159 #define MSS_GPIO_26_MASK 0x04000000UL
\r
160 #define MSS_GPIO_27_MASK 0x08000000UL
\r
161 #define MSS_GPIO_28_MASK 0x10000000UL
\r
162 #define MSS_GPIO_29_MASK 0x20000000UL
\r
163 #define MSS_GPIO_30_MASK 0x40000000UL
\r
164 #define MSS_GPIO_31_MASK 0x80000000UL
\r
166 /*-------------------------------------------------------------------------*//**
\r
169 #define MSS_GPIO_INPUT_MODE 0x0000000002UL
\r
170 #define MSS_GPIO_OUTPUT_MODE 0x0000000005UL
\r
171 #define MSS_GPIO_INOUT_MODE 0x0000000003UL
\r
173 /*-------------------------------------------------------------------------*//**
\r
174 * Possible GPIO inputs interrupt configurations.
\r
176 #define MSS_GPIO_IRQ_LEVEL_HIGH 0x0000000000UL
\r
177 #define MSS_GPIO_IRQ_LEVEL_LOW 0x0000000020UL
\r
178 #define MSS_GPIO_IRQ_EDGE_POSITIVE 0x0000000040UL
\r
179 #define MSS_GPIO_IRQ_EDGE_NEGATIVE 0x0000000060UL
\r
180 #define MSS_GPIO_IRQ_EDGE_BOTH 0x0000000080UL
\r
182 /*-------------------------------------------------------------------------*//**
\r
183 * Possible states for GPIO configured as INOUT.
\r
185 typedef enum mss_gpio_inout_state
\r
187 MSS_GPIO_DRIVE_LOW = 0,
\r
188 MSS_GPIO_DRIVE_HIGH,
\r
190 } mss_gpio_inout_state_t;
\r
192 /*-------------------------------------------------------------------------*//**
\r
193 The MSS_GPIO_init() function initializes the SmartFusion MSS GPIO block. It
\r
194 resets the MSS GPIO hardware block and it also clears any pending MSS GPIO
\r
195 interrupts in the Cortex-M3 interrupt controller.
\r
200 void MSS_GPIO_init( void );
\r
202 /*-------------------------------------------------------------------------*//**
\r
203 The MSS_GPIO_config() function is used to configure an individual
\r
207 The port_id parameter identifies the GPIO port to be configured.
\r
208 An enumeration item of the form MSS_GPIO_n where n is the number of the GPIO
\r
209 port is used to identify the GPIO port. For example MSS_GPIO_0 identifies
\r
210 the first GPIO port and MSS_GPIO_31 the last one.
\r
213 The config parameter specifies the configuration to be applied to the GPIO
\r
214 port identified by the port_id parameter. It is a logical OR of the required
\r
215 I/O mode and the required interrupt mode. The interrupt mode is not relevant
\r
216 if the GPIO is configured as an output only.
\r
217 These I/O mode constants are allowed:
\r
218 - MSS_GPIO_INPUT_MODE
\r
219 - MSS_GPIO_OUTPUT_MODE
\r
220 - MSS_GPIO_INOUT_MODE
\r
221 These interrupt mode constants are allowed:
\r
222 - MSS_GPIO_IRQ_LEVEL_HIGH
\r
223 - MSS_GPIO_IRQ_LEVEL_LOW
\r
224 - MSS_GPIO_IRQ_EDGE_POSITIVE
\r
225 - MSS_GPIO_IRQ_EDGE_NEGATIVE
\r
226 - MSS_GPIO_IRQ_EDGE_BOTH
\r
232 The following call will configure GPIO 4 as an input generating interrupts on
\r
233 a low to high transition of the input:
\r
235 MSS_GPIO_config( MSS_GPIO_4, MSS_GPIO_INPUT_MODE | MSS_GPIO_IRQ_EDGE_POSITIVE );
\r
238 void MSS_GPIO_config
\r
240 mss_gpio_id_t port_id,
\r
244 /*-------------------------------------------------------------------------*//**
\r
245 The MSS_GPIO_set_outputs() function is used to set the state of all GPIO
\r
246 ports configured as outputs.
\r
249 The value parameter specifies the state of the GPIO ports configured as
\r
250 outputs. It is a bit mask of the form (MSS_GPIO_n_MASK | MSS_GPIO_m_MASK) where n
\r
251 and m are numbers identifying GPIOs.
\r
252 For example (MSS_GPIO_0_MASK | MSS_GPIO_1_MASK | MSS_GPIO_2_MASK ) specifies
\r
253 that the first, second and third GPIOs' must be set high and all other
\r
255 The driver provides 32 mask constants, MSS_GPIO_0_MASK to MSS_GPIO_31_MASK
\r
256 inclusive, for this purpose.
\r
262 Set GPIOs outputs 0 and 8 high and all other GPIO outputs low.
\r
264 MSS_GPIO_set_outputs( MSS_GPIO_0_MASK | MSS_GPIO_8_MASK );
\r
268 Set GPIOs outputs 2 and 4 low without affecting other GPIO outputs.
\r
270 uint32_t gpio_outputs;
\r
271 gpio_outputs = MSS_GPIO_get_outputs();
\r
272 gpio_outputs &= ~( MSS_GPIO_2_MASK | MSS_GPIO_4_MASK );
\r
273 MSS_GPIO_set_outputs( gpio_outputs );
\r
276 @see MSS_GPIO_get_outputs()
\r
278 static __INLINE void
\r
279 MSS_GPIO_set_outputs
\r
284 GPIO->GPIO_OUT = value;
\r
287 /*-------------------------------------------------------------------------*//**
\r
288 The MSS_GPIO_set_output() function is used to set the state of a single GPIO
\r
289 port configured as output.
\r
292 The port_id parameter identifies the GPIO port that is to have its output set.
\r
293 An enumeration item of the form MSS_GPIO_n where n is the number of the GPIO
\r
294 port is used to identify the GPIO port. For example MSS_GPIO_0 identifies the
\r
295 first GPIO port and MSS_GPIO_31 the last one.
\r
298 The value parameter specifies the desired state for the GPIO output. A value
\r
299 of 0 will set the output low and a value of 1 will set the output high.
\r
304 void MSS_GPIO_set_output
\r
306 mss_gpio_id_t port_id,
\r
310 /*-------------------------------------------------------------------------*//**
\r
311 The MSS_GPIO_get_inputs() function is used to read the current state of all
\r
312 GPIO ports confgured as inputs.
\r
315 This function returns a 32 bit unsigned integer where each bit represents
\r
316 the state of a GPIO input. The least significant bit represents the state of
\r
317 GPIO input 0 and the most significant bit the state of GPIO input 31.
\r
320 Read and assign the current state of the GPIO outputs to a variable.
\r
322 uint32_t gpio_inputs;
\r
323 gpio_inputs = MSS_GPIO_get_inputs();
\r
326 static __INLINE uint32_t
\r
327 MSS_GPIO_get_inputs( void )
\r
329 return GPIO->GPIO_IN;
\r
332 /*-------------------------------------------------------------------------*//**
\r
333 The MSS_GPIO_get_outputs() function is used to read the current state of all
\r
334 GPIO ports confgured as outputs.
\r
337 This function returns a 32 bit unsigned integer where each bit represents
\r
338 the state of a GPIO output. The least significant bit represents the state
\r
339 of GPIO output 0 and the most significant bit the state of GPIO output 31.
\r
342 Read and assign the current state of the GPIO outputs to a variable.
\r
344 uint32_t gpio_outputs;
\r
345 gpio_outputs = MSS_GPIO_get_outputs();
\r
348 static __INLINE uint32_t
\r
349 MSS_GPIO_get_outputs( void )
\r
351 return GPIO->GPIO_OUT;
\r
354 /*-------------------------------------------------------------------------*//**
\r
355 The MSS_GPIO_drive_inout() function is used to set the output state of a single
\r
356 GPIO port configured as an INOUT. An INOUT GPIO can be in one of three states:
\r
360 An INOUT output would typically be used where several devices can drive the
\r
361 state of a shared signal line. The high and low states are equivalent to the
\r
362 high and low states of a GPIO configured as output. The high impedance state
\r
363 is used to prevent the GPIO from driving its output state onto the signal line,
\r
364 while at the same time allowing the input state of the GPIO to be read
\r
367 The port_id parameter identifies the GPIO port for which you want to change
\r
369 An enumeration item of the form MSS_GPIO_n where n is the number of the GPIO
\r
370 port is used to identify the GPIO port. For example MSS_GPIO_0 identifies
\r
371 the first GPIO port and MSS_GPIO_31 the last one.
\r
374 The inout_state parameter specifies the state of the GPIO port identified by
\r
375 the port_id parameter. Allowed values of type mss_gpio_inout_state_t are:
\r
376 - MSS_GPIO_DRIVE_HIGH
\r
377 - MSS_GPIO_DRIVE_LOW
\r
378 - MSS_GPIO_HIGH_Z (high impedance)
\r
384 The call to MSS_GPIO_drive_inout() below will set the GPIO 7 output to the
\r
385 high impedance state.
\r
387 MSS_GPIO_drive_inout( MSS_GPIO_7, MSS_GPIO_HIGH_Z );
\r
390 void MSS_GPIO_drive_inout
\r
392 mss_gpio_id_t port_id,
\r
393 mss_gpio_inout_state_t inout_state
\r
396 /*-------------------------------------------------------------------------*//**
\r
397 The MSS_GPIO_enable_irq() function is used to enable interrupt generation
\r
398 for the specified GPIO input. Interrupts are generated based on the state of
\r
399 the GPIO input and the interrupt mode configured for it by MSS_GPIO_config().
\r
402 The port_id parameter identifies the GPIO port for which you want to enable
\r
403 interrupt generation.
\r
404 An enumeration item of the form MSS_GPIO_n where n is the number of the GPIO
\r
405 port is used to identify the GPIO port. For example MSS_GPIO_0 identifies the
\r
406 first GPIO port and MSS_GPIO_31 the last one.
\r
412 The call to MSS_GPIO_enable_irq() below will allow GPIO 8 to generate
\r
415 MSS_GPIO_enable_irq( MSS_GPIO_8 );
\r
418 void MSS_GPIO_enable_irq
\r
420 mss_gpio_id_t port_id
\r
423 /*-------------------------------------------------------------------------*//**
\r
424 The MSS_GPIO_disable_irq() function is used to disable interrupt generation
\r
425 for the specified GPIO input.
\r
428 The port_id parameter identifies the GPIO port for which you want to disable
\r
429 interrupt generation.
\r
430 An enumeration item of the form MSS_GPIO_n where n is the number of the GPIO
\r
431 port is used to identify the GPIO port. For example MSS_GPIO_0 identifies the
\r
432 first GPIO port and MSS_GPIO_31 the last one.
\r
438 The call to MSS_GPIO_disable_irq() below will prevent GPIO 8 from generating
\r
441 MSS_GPIO_disable_irq( MSS_GPIO_8 );
\r
444 void MSS_GPIO_disable_irq
\r
446 mss_gpio_id_t port_id
\r
449 /*-------------------------------------------------------------------------*//**
\r
450 The MSS_GPIO_clear_irq() function is used to clear a pending interrupt from
\r
451 the specified GPIO input.
\r
452 Note: The MSS_GPIO_clear_irq() function must be called as part of any GPIO
\r
453 interrupt service routine (ISR) in order to prevent the same interrupt event
\r
454 retriggering a call to the GPIO ISR. The function also clears the interrupt
\r
455 in the Cortex-M3 interrupt controller through a call to NVIC_ClearPendingIRQ().
\r
458 The port_id parameter identifies the GPIO input for which you want to clear the
\r
460 An enumeration item of the form MSS_GPIO_n where n is the number of the GPIO
\r
461 port is used to identify the GPIO port. For example MSS_GPIO_0 identifies the
\r
462 first GPIO port and MSS_GPIO_31 the last one.
\r
468 The example below demonstrates the use of the MSS_GPIO_clear_irq() function
\r
469 as part of the GPIO 9 interrupt service routine.
\r
471 void GPIO9_IRQHandler( void )
\r
473 do_interrupt_processing();
\r
475 MSS_GPIO_clear_irq( MSS_GPIO_9 );
\r
479 void MSS_GPIO_clear_irq
\r
481 mss_gpio_id_t port_id
\r
488 #endif /* MSS_GPIO_H_ */
\r