1 /*******************************************************************************
\r
2 * (c) Copyright 2008 Actel Corporation. All rights reserved.
\r
4 * SmartFusion microcontroller subsystem GPIO bare metal driver implementation.
\r
6 * SVN $Revision: 1753 $
\r
7 * SVN $Date: 2009-12-11 15:12:18 +0000 (Fri, 11 Dec 2009) $
\r
9 #include "mss_gpio.h"
\r
10 #include "../../CMSIS/mss_assert.h"
\r
16 /*-------------------------------------------------------------------------*//**
\r
19 #define GPIO_INT_ENABLE_MASK (uint32_t)0x00000008UL
\r
20 #define OUTPUT_BUFFER_ENABLE_MASK 0x00000004UL
\r
22 #define NB_OF_GPIO (uint32_t)32
\r
24 /*-------------------------------------------------------------------------*//**
\r
25 * Lookup table of GPIO configuration registers address indexed on GPIO ID.
\r
27 static uint32_t volatile * const g_config_reg_lut[NB_OF_GPIO] =
\r
29 &(GPIO->GPIO_0_CFG),
\r
30 &(GPIO->GPIO_1_CFG),
\r
31 &(GPIO->GPIO_2_CFG),
\r
32 &(GPIO->GPIO_3_CFG),
\r
33 &(GPIO->GPIO_4_CFG),
\r
34 &(GPIO->GPIO_5_CFG),
\r
35 &(GPIO->GPIO_6_CFG),
\r
36 &(GPIO->GPIO_7_CFG),
\r
37 &(GPIO->GPIO_8_CFG),
\r
38 &(GPIO->GPIO_9_CFG),
\r
39 &(GPIO->GPIO_10_CFG),
\r
40 &(GPIO->GPIO_11_CFG),
\r
41 &(GPIO->GPIO_12_CFG),
\r
42 &(GPIO->GPIO_13_CFG),
\r
43 &(GPIO->GPIO_14_CFG),
\r
44 &(GPIO->GPIO_15_CFG),
\r
45 &(GPIO->GPIO_16_CFG),
\r
46 &(GPIO->GPIO_17_CFG),
\r
47 &(GPIO->GPIO_18_CFG),
\r
48 &(GPIO->GPIO_19_CFG),
\r
49 &(GPIO->GPIO_20_CFG),
\r
50 &(GPIO->GPIO_21_CFG),
\r
51 &(GPIO->GPIO_22_CFG),
\r
52 &(GPIO->GPIO_23_CFG),
\r
53 &(GPIO->GPIO_24_CFG),
\r
54 &(GPIO->GPIO_25_CFG),
\r
55 &(GPIO->GPIO_26_CFG),
\r
56 &(GPIO->GPIO_27_CFG),
\r
57 &(GPIO->GPIO_28_CFG),
\r
58 &(GPIO->GPIO_29_CFG),
\r
59 &(GPIO->GPIO_30_CFG),
\r
60 &(GPIO->GPIO_31_CFG)
\r
63 /*-------------------------------------------------------------------------*//**
\r
64 * Lookup table of Cortex-M3 GPIO interrupt number indexed on GPIO ID.
\r
66 static const IRQn_Type g_gpio_irqn_lut[NB_OF_GPIO] =
\r
102 /*-------------------------------------------------------------------------*//**
\r
104 * See "mss_gpio.h" for details of how to use this function.
\r
106 void MSS_GPIO_init( void )
\r
110 /* reset MSS GPIO hardware */
\r
111 SYSREG->SOFT_RST_CR |= SYSREG_GPIO_SOFTRESET_MASK;
\r
112 /* Clear any previously pended MSS GPIO interrupt */
\r
113 for ( i = 0U; i < NB_OF_GPIO; ++i )
\r
115 NVIC_ClearPendingIRQ( g_gpio_irqn_lut[i] );
\r
117 /* Take MSS GPIO hardware out of reset. */
\r
118 SYSREG->SOFT_RST_CR &= ~SYSREG_GPIO_SOFTRESET_MASK;
\r
121 /*-------------------------------------------------------------------------*//**
\r
123 * See "mss_gpio.h" for details of how to use this function.
\r
125 void MSS_GPIO_config
\r
127 mss_gpio_id_t port_id,
\r
131 uint32_t gpio_idx = (uint32_t)port_id;
\r
133 ASSERT( gpio_idx < NB_OF_GPIO );
\r
135 if ( gpio_idx < NB_OF_GPIO )
\r
137 *(g_config_reg_lut[gpio_idx]) = config;
\r
141 /*-------------------------------------------------------------------------*//**
\r
142 * MSS_GPIO_set_output
\r
143 * See "mss_gpio.h" for details of how to use this function.
\r
145 void MSS_GPIO_set_output
\r
147 mss_gpio_id_t port_id,
\r
151 uint32_t gpio_idx = (uint32_t)port_id;
\r
153 ASSERT( gpio_idx < NB_OF_GPIO );
\r
155 if ( gpio_idx < NB_OF_GPIO )
\r
157 GPIO_BITBAND->GPIO_OUT[gpio_idx] = (uint32_t)value;
\r
161 /*-------------------------------------------------------------------------*//**
\r
162 * MSS_GPIO_drive_inout
\r
163 * See "mss_gpio.h" for details of how to use this function.
\r
165 void MSS_GPIO_drive_inout
\r
167 mss_gpio_id_t port_id,
\r
168 mss_gpio_inout_state_t inout_state
\r
171 uint32_t outputs_state;
\r
173 uint32_t gpio_idx = (uint32_t)port_id;
\r
175 ASSERT( gpio_idx < NB_OF_GPIO );
\r
177 if ( gpio_idx < NB_OF_GPIO )
\r
179 switch( inout_state )
\r
181 case MSS_GPIO_DRIVE_HIGH:
\r
182 /* Set output high */
\r
183 outputs_state = GPIO->GPIO_OUT;
\r
184 outputs_state |= (uint32_t)1 << gpio_idx;
\r
185 GPIO->GPIO_OUT = outputs_state;
\r
186 /* Enable output buffer */
\r
187 config = *(g_config_reg_lut[gpio_idx]);
\r
188 config |= OUTPUT_BUFFER_ENABLE_MASK;
\r
189 *(g_config_reg_lut[gpio_idx]) = config;
\r
192 case MSS_GPIO_DRIVE_LOW:
\r
193 /* Set output low */
\r
194 outputs_state = GPIO->GPIO_OUT;
\r
195 outputs_state &= ~((uint32_t)((uint32_t)1 << gpio_idx));
\r
196 GPIO->GPIO_OUT = outputs_state;
\r
197 /* Enable output buffer */
\r
198 config = *(g_config_reg_lut[gpio_idx]);
\r
199 config |= OUTPUT_BUFFER_ENABLE_MASK;
\r
200 *(g_config_reg_lut[gpio_idx]) = config;
\r
203 case MSS_GPIO_HIGH_Z:
\r
204 /* Disable output buffer */
\r
205 config = *(g_config_reg_lut[gpio_idx]);
\r
206 config &= ~OUTPUT_BUFFER_ENABLE_MASK;
\r
207 *(g_config_reg_lut[gpio_idx]) = config;
\r
217 /*-------------------------------------------------------------------------*//**
\r
218 * MSS_GPIO_enable_irq
\r
219 * See "mss_gpio.h" for details of how to use this function.
\r
221 void MSS_GPIO_enable_irq
\r
223 mss_gpio_id_t port_id
\r
226 uint32_t cfg_value;
\r
227 uint32_t gpio_idx = (uint32_t)port_id;
\r
229 ASSERT( gpio_idx < NB_OF_GPIO );
\r
231 if ( gpio_idx < NB_OF_GPIO )
\r
233 cfg_value = *(g_config_reg_lut[gpio_idx]);
\r
234 *(g_config_reg_lut[gpio_idx]) = (cfg_value | GPIO_INT_ENABLE_MASK);
\r
235 NVIC_EnableIRQ( g_gpio_irqn_lut[gpio_idx] );
\r
239 /*-------------------------------------------------------------------------*//**
\r
240 * MSS_GPIO_disable_irq
\r
241 * See "mss_gpio.h" for details of how to use this function.
\r
243 void MSS_GPIO_disable_irq
\r
245 mss_gpio_id_t port_id
\r
248 uint32_t cfg_value;
\r
249 uint32_t gpio_idx = (uint32_t)port_id;
\r
251 ASSERT( gpio_idx < NB_OF_GPIO );
\r
253 if ( gpio_idx < NB_OF_GPIO )
\r
255 cfg_value = *(g_config_reg_lut[gpio_idx]);
\r
256 *(g_config_reg_lut[gpio_idx]) = (cfg_value & ~GPIO_INT_ENABLE_MASK);
\r
260 /*-------------------------------------------------------------------------*//**
\r
261 * MSS_GPIO_clear_irq
\r
262 * See "mss_gpio.h" for details of how to use this function.
\r
264 void MSS_GPIO_clear_irq
\r
266 mss_gpio_id_t port_id
\r
269 uint32_t gpio_idx = (uint32_t)port_id;
\r
271 ASSERT( gpio_idx < NB_OF_GPIO );
\r
273 if ( gpio_idx < NB_OF_GPIO )
\r
275 GPIO->GPIO_IRQ = ((uint32_t)1) << gpio_idx;
\r
276 NVIC_ClearPendingIRQ( g_gpio_irqn_lut[gpio_idx] );
\r