]> git.sur5r.net Git - freertos/blob
096a8279463258f76878a9371c74bad45fe0d2ca
[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 driver implementation.\r
5  *\r
6  * SVN $Revision: 5394 $\r
7  * SVN $Date: 2013-03-27 20:56:36 +0000 (Wed, 27 Mar 2013) $\r
8  */\r
9 #include "mss_gpio.h"\r
10 #include "../../CMSIS/mss_assert.h"\r
11 \r
12 #ifdef __cplusplus\r
13 extern "C" {\r
14 #endif \r
15 \r
16 /*-------------------------------------------------------------------------*//**\r
17  * Defines.\r
18  */\r
19 #define GPIO_INT_ENABLE_MASK        ((uint32_t)0x00000008uL)\r
20 #define OUTPUT_BUFFER_ENABLE_MASK   0x00000004u\r
21 \r
22 #define NB_OF_GPIO  ((uint32_t)32)\r
23 \r
24 /*-------------------------------------------------------------------------*//**\r
25  * Lookup table of GPIO configuration registers address indexed on GPIO ID.\r
26  */\r
27 static uint32_t volatile * const g_config_reg_lut[NB_OF_GPIO] =\r
28 {\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
61 };\r
62 \r
63 /*-------------------------------------------------------------------------*//**\r
64  * Lookup table of Cortex-M3 GPIO interrupt number indexed on GPIO ID.\r
65  */\r
66 static const IRQn_Type g_gpio_irqn_lut[NB_OF_GPIO] =\r
67 {\r
68     GPIO0_IRQn,\r
69     GPIO1_IRQn,\r
70     GPIO2_IRQn,\r
71     GPIO3_IRQn,\r
72     GPIO4_IRQn,\r
73     GPIO5_IRQn,\r
74     GPIO6_IRQn,\r
75     GPIO7_IRQn,\r
76     GPIO8_IRQn,\r
77     GPIO9_IRQn,\r
78     GPIO10_IRQn,\r
79     GPIO11_IRQn,\r
80     GPIO12_IRQn,\r
81     GPIO13_IRQn,\r
82     GPIO14_IRQn,\r
83     GPIO15_IRQn,\r
84     GPIO16_IRQn,\r
85     GPIO17_IRQn,\r
86     GPIO18_IRQn,\r
87     GPIO19_IRQn,\r
88     GPIO20_IRQn,\r
89     GPIO21_IRQn,\r
90     GPIO22_IRQn,\r
91     GPIO23_IRQn,\r
92     GPIO24_IRQn,\r
93     GPIO25_IRQn,\r
94     GPIO26_IRQn,\r
95     GPIO27_IRQn,\r
96     GPIO28_IRQn,\r
97     GPIO29_IRQn,\r
98     GPIO30_IRQn,\r
99     GPIO31_IRQn\r
100 };\r
101 \r
102 /*-------------------------------------------------------------------------*//**\r
103  * MSS_GPIO_init\r
104  * See "mss_gpio.h" for details of how to use this function.\r
105  */\r
106 void MSS_GPIO_init( void )\r
107 {\r
108     uint32_t inc;\r
109     \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
116                             \r
117     /* Clear any previously pended MSS GPIO interrupt */\r
118     for(inc = 0U; inc < NB_OF_GPIO; ++inc)\r
119     {\r
120         NVIC_DisableIRQ(g_gpio_irqn_lut[inc]);\r
121         NVIC_ClearPendingIRQ(g_gpio_irqn_lut[inc]);\r
122     }\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
129 }\r
130 \r
131 /*-------------------------------------------------------------------------*//**\r
132  * MSS_GPIO_config\r
133  * See "mss_gpio.h" for details of how to use this function.\r
134  */\r
135 void MSS_GPIO_config\r
136 (\r
137     mss_gpio_id_t port_id,\r
138     uint32_t config\r
139 )\r
140 {\r
141     uint32_t gpio_idx = (uint32_t)port_id;\r
142     \r
143     ASSERT(gpio_idx < NB_OF_GPIO);\r
144 \r
145     if(gpio_idx < NB_OF_GPIO)\r
146     {\r
147         *(g_config_reg_lut[gpio_idx]) = config;\r
148     }\r
149 }\r
150 \r
151 /*-------------------------------------------------------------------------*//**\r
152  * MSS_GPIO_set_output\r
153  * See "mss_gpio.h" for details of how to use this function.\r
154  */\r
155 void MSS_GPIO_set_output\r
156 (\r
157     mss_gpio_id_t port_id,\r
158     uint8_t value\r
159 )\r
160 {\r
161     uint32_t gpio_setting;\r
162     uint32_t gpio_idx = (uint32_t)port_id;\r
163     \r
164     ASSERT(gpio_idx < NB_OF_GPIO);\r
165     \r
166     if(gpio_idx < NB_OF_GPIO)\r
167     {\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
172     }\r
173 }\r
174 \r
175 /*-------------------------------------------------------------------------*//**\r
176  * MSS_GPIO_drive_inout\r
177  * See "mss_gpio.h" for details of how to use this function.\r
178  */\r
179 void MSS_GPIO_drive_inout\r
180 (\r
181     mss_gpio_id_t port_id,\r
182     mss_gpio_inout_state_t inout_state\r
183 )\r
184 {\r
185     uint32_t outputs_state;\r
186     uint32_t config;\r
187     uint32_t gpio_idx = (uint32_t)port_id;\r
188     \r
189     ASSERT(gpio_idx < NB_OF_GPIO);\r
190     \r
191     if(gpio_idx < NB_OF_GPIO)\r
192     {\r
193         switch(inout_state)\r
194         {\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
204             break;\r
205                 \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
215             break;\r
216                 \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
222             break;\r
223                 \r
224             default:\r
225                 ASSERT(0);\r
226             break;\r
227         }\r
228     }\r
229 }\r
230 \r
231 /*-------------------------------------------------------------------------*//**\r
232  * MSS_GPIO_enable_irq\r
233  * See "mss_gpio.h" for details of how to use this function.\r
234  */\r
235 void MSS_GPIO_enable_irq\r
236 (\r
237     mss_gpio_id_t port_id\r
238 )\r
239 {\r
240     uint32_t cfg_value;\r
241     uint32_t gpio_idx = (uint32_t)port_id;\r
242     \r
243     ASSERT(gpio_idx < NB_OF_GPIO);\r
244     \r
245     if(gpio_idx < NB_OF_GPIO)\r
246     {\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
250     }\r
251 }\r
252 \r
253 /*-------------------------------------------------------------------------*//**\r
254  * MSS_GPIO_disable_irq\r
255  * See "mss_gpio.h" for details of how to use this function.\r
256  */\r
257 void MSS_GPIO_disable_irq\r
258 (\r
259     mss_gpio_id_t port_id\r
260 )\r
261 {\r
262     uint32_t cfg_value;\r
263     uint32_t gpio_idx = (uint32_t)port_id;\r
264     \r
265     ASSERT(gpio_idx < NB_OF_GPIO);\r
266 \r
267     if(gpio_idx < NB_OF_GPIO)\r
268     {\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
271     }\r
272 }\r
273 \r
274 /*-------------------------------------------------------------------------*//**\r
275  * MSS_GPIO_clear_irq\r
276  * See "mss_gpio.h" for details of how to use this function.\r
277  */\r
278 void MSS_GPIO_clear_irq\r
279 (\r
280     mss_gpio_id_t port_id\r
281 )\r
282 {\r
283     uint32_t gpio_idx = (uint32_t)port_id;\r
284     \r
285     ASSERT(gpio_idx < NB_OF_GPIO);\r
286     \r
287     if(gpio_idx < NB_OF_GPIO)\r
288     {\r
289         GPIO->GPIO_IRQ = ((uint32_t)1) << gpio_idx;\r
290     }\r
291 }\r
292 \r
293 #ifdef __cplusplus\r
294 }\r
295 #endif\r
296 \r