1 /*******************************************************************************
\r
2 * (c) Copyright 2008-2013 Microsemi SoC Products Group. All rights reserved.
\r
4 * SmartFusion2 microcontroller subsystem GPIO bare metal driver implementation.
\r
6 * SVN $Revision: 5394 $
\r
7 * SVN $Date: 2013-03-27 20:56:36 +0000 (Wed, 27 Mar 2013) $
\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 0x00000004u
\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 SYSREG->SOFT_RST_CR |= (SYSREG_GPIO_7_0_SOFTRESET_MASK |
\r
113 SYSREG_GPIO_15_8_SOFTRESET_MASK |
\r
114 SYSREG_GPIO_23_16_SOFTRESET_MASK |
\r
115 SYSREG_GPIO_31_24_SOFTRESET_MASK);
\r
117 /* Clear any previously pended MSS GPIO interrupt */
\r
118 for(inc = 0U; inc < NB_OF_GPIO; ++inc)
\r
120 NVIC_DisableIRQ(g_gpio_irqn_lut[inc]);
\r
121 NVIC_ClearPendingIRQ(g_gpio_irqn_lut[inc]);
\r
123 /* Take MSS GPIO hardware out of reset. */
\r
124 SYSREG->SOFT_RST_CR &= ~(SYSREG_GPIO_7_0_SOFTRESET_MASK |
\r
125 SYSREG_GPIO_15_8_SOFTRESET_MASK |
\r
126 SYSREG_GPIO_23_16_SOFTRESET_MASK |
\r
127 SYSREG_GPIO_31_24_SOFTRESET_MASK);
\r
128 SYSREG->SOFT_RST_CR &= ~SYSREG_GPIO_SOFTRESET_MASK;
\r
131 /*-------------------------------------------------------------------------*//**
\r
133 * See "mss_gpio.h" for details of how to use this function.
\r
135 void MSS_GPIO_config
\r
137 mss_gpio_id_t port_id,
\r
141 uint32_t gpio_idx = (uint32_t)port_id;
\r
143 ASSERT(gpio_idx < NB_OF_GPIO);
\r
145 if(gpio_idx < NB_OF_GPIO)
\r
147 *(g_config_reg_lut[gpio_idx]) = config;
\r
151 /*-------------------------------------------------------------------------*//**
\r
152 * MSS_GPIO_set_output
\r
153 * See "mss_gpio.h" for details of how to use this function.
\r
155 void MSS_GPIO_set_output
\r
157 mss_gpio_id_t port_id,
\r
161 uint32_t gpio_setting;
\r
162 uint32_t gpio_idx = (uint32_t)port_id;
\r
164 ASSERT(gpio_idx < NB_OF_GPIO);
\r
166 if(gpio_idx < NB_OF_GPIO)
\r
168 gpio_setting = GPIO->GPIO_OUT;
\r
169 gpio_setting &= ~((uint32_t)0x01u << gpio_idx);
\r
170 gpio_setting |= ((uint32_t)value & 0x01u) << gpio_idx;
\r
171 GPIO->GPIO_OUT = gpio_setting;
\r
175 /*-------------------------------------------------------------------------*//**
\r
176 * MSS_GPIO_drive_inout
\r
177 * See "mss_gpio.h" for details of how to use this function.
\r
179 void MSS_GPIO_drive_inout
\r
181 mss_gpio_id_t port_id,
\r
182 mss_gpio_inout_state_t inout_state
\r
185 uint32_t outputs_state;
\r
187 uint32_t gpio_idx = (uint32_t)port_id;
\r
189 ASSERT(gpio_idx < NB_OF_GPIO);
\r
191 if(gpio_idx < NB_OF_GPIO)
\r
193 switch(inout_state)
\r
195 case MSS_GPIO_DRIVE_HIGH:
\r
196 /* Set output high */
\r
197 outputs_state = GPIO->GPIO_OUT;
\r
198 outputs_state |= (uint32_t)1 << gpio_idx;
\r
199 GPIO->GPIO_OUT = outputs_state;
\r
200 /* Enable output buffer */
\r
201 config = *(g_config_reg_lut[gpio_idx]);
\r
202 config |= OUTPUT_BUFFER_ENABLE_MASK;
\r
203 *(g_config_reg_lut[gpio_idx]) = config;
\r
206 case MSS_GPIO_DRIVE_LOW:
\r
207 /* Set output low */
\r
208 outputs_state = GPIO->GPIO_OUT;
\r
209 outputs_state &= ~((uint32_t)((uint32_t)1 << gpio_idx));
\r
210 GPIO->GPIO_OUT = outputs_state;
\r
211 /* Enable output buffer */
\r
212 config = *(g_config_reg_lut[gpio_idx]);
\r
213 config |= OUTPUT_BUFFER_ENABLE_MASK;
\r
214 *(g_config_reg_lut[gpio_idx]) = config;
\r
217 case MSS_GPIO_HIGH_Z:
\r
218 /* Disable output buffer */
\r
219 config = *(g_config_reg_lut[gpio_idx]);
\r
220 config &= ~OUTPUT_BUFFER_ENABLE_MASK;
\r
221 *(g_config_reg_lut[gpio_idx]) = config;
\r
231 /*-------------------------------------------------------------------------*//**
\r
232 * MSS_GPIO_enable_irq
\r
233 * See "mss_gpio.h" for details of how to use this function.
\r
235 void MSS_GPIO_enable_irq
\r
237 mss_gpio_id_t port_id
\r
240 uint32_t cfg_value;
\r
241 uint32_t gpio_idx = (uint32_t)port_id;
\r
243 ASSERT(gpio_idx < NB_OF_GPIO);
\r
245 if(gpio_idx < NB_OF_GPIO)
\r
247 cfg_value = *(g_config_reg_lut[gpio_idx]);
\r
248 *(g_config_reg_lut[gpio_idx]) = (cfg_value | GPIO_INT_ENABLE_MASK);
\r
249 NVIC_EnableIRQ(g_gpio_irqn_lut[gpio_idx]);
\r
253 /*-------------------------------------------------------------------------*//**
\r
254 * MSS_GPIO_disable_irq
\r
255 * See "mss_gpio.h" for details of how to use this function.
\r
257 void MSS_GPIO_disable_irq
\r
259 mss_gpio_id_t port_id
\r
262 uint32_t cfg_value;
\r
263 uint32_t gpio_idx = (uint32_t)port_id;
\r
265 ASSERT(gpio_idx < NB_OF_GPIO);
\r
267 if(gpio_idx < NB_OF_GPIO)
\r
269 cfg_value = *(g_config_reg_lut[gpio_idx]);
\r
270 *(g_config_reg_lut[gpio_idx]) = (cfg_value & ~GPIO_INT_ENABLE_MASK);
\r
274 /*-------------------------------------------------------------------------*//**
\r
275 * MSS_GPIO_clear_irq
\r
276 * See "mss_gpio.h" for details of how to use this function.
\r
278 void MSS_GPIO_clear_irq
\r
280 mss_gpio_id_t port_id
\r
283 uint32_t gpio_idx = (uint32_t)port_id;
\r
285 ASSERT(gpio_idx < NB_OF_GPIO);
\r
287 if(gpio_idx < NB_OF_GPIO)
\r
289 GPIO->GPIO_IRQ = ((uint32_t)1) << gpio_idx;
\r