1 /*!
2 * \file gpio-board.c
3 *
4 * \brief Target board GPIO driver implementation
5 *
6 * \copyright Revised BSD License, see section \ref LICENSE.
7 *
8 * \code
9 * ______ _
10 * / _____) _ | |
11 * ( (____ _____ ____ _| |_ _____ ____| |__
12 * \____ \| ___ | (_ _) ___ |/ ___) _ \
13 * _____) ) ____| | | || |_| ____( (___| | | |
14 * (______/|_____)_|_|_| \__)_____)\____)_| |_|
15 * (C)2013-2017 Semtech
16 *
17 * \endcode
18 *
19 * \author Miguel Luis ( Semtech )
20 *
21 * \author Gregory Cristian ( Semtech )
22 */
23 #include "stm32l4xx.h"
24 #include "utilities.h"
25 #include "sysIrqHandlers.h"
26 #include "board-config.h"
27 #include "rtc-board.h"
28 #include "gpio-board.h"
29 #if defined( BOARD_IOE_EXT )
30 #include "gpio-ioe.h"
31 #endif
32
33 static Gpio_t *GpioIrq[16];
34
GpioMcuInit(Gpio_t * obj,PinNames pin,PinModes mode,PinConfigs config,PinTypes type,uint32_t value)35 void GpioMcuInit( Gpio_t *obj, PinNames pin, PinModes mode, PinConfigs config, PinTypes type, uint32_t value )
36 {
37 if( pin < IOE_0 )
38 {
39 GPIO_InitTypeDef GPIO_InitStructure;
40
41 obj->pin = pin;
42
43 if( pin == NC )
44 {
45 return;
46 }
47
48 obj->pinIndex = ( 0x01 << ( obj->pin & 0x0F ) );
49
50 if( ( obj->pin & 0xF0 ) == 0x00 )
51 {
52 obj->port = GPIOA;
53 __HAL_RCC_GPIOA_CLK_ENABLE( );
54 }
55 else if( ( obj->pin & 0xF0 ) == 0x10 )
56 {
57 obj->port = GPIOB;
58 __HAL_RCC_GPIOB_CLK_ENABLE( );
59 }
60 else if( ( obj->pin & 0xF0 ) == 0x20 )
61 {
62 obj->port = GPIOC;
63 __HAL_RCC_GPIOC_CLK_ENABLE( );
64 }
65 else if( ( obj->pin & 0xF0 ) == 0x30 )
66 {
67 obj->port = GPIOD;
68 __HAL_RCC_GPIOD_CLK_ENABLE( );
69 }
70 else
71 {
72 obj->port = GPIOH;
73 __HAL_RCC_GPIOH_CLK_ENABLE( );
74 }
75
76 GPIO_InitStructure.Pin = obj->pinIndex ;
77 GPIO_InitStructure.Pull = obj->pull = type;
78 GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
79
80 if( mode == PIN_INPUT )
81 {
82 GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
83 }
84 else if( mode == PIN_ANALOGIC )
85 {
86 GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
87 }
88 else if( mode == PIN_ALTERNATE_FCT )
89 {
90 if( config == PIN_OPEN_DRAIN )
91 {
92 GPIO_InitStructure.Mode = GPIO_MODE_AF_OD;
93 }
94 else
95 {
96 GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
97 }
98 GPIO_InitStructure.Alternate = value;
99 }
100 else // mode output
101 {
102 if( config == PIN_OPEN_DRAIN )
103 {
104 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
105 }
106 else
107 {
108 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
109 }
110 }
111
112 // Sets initial output value
113 if( mode == PIN_OUTPUT )
114 {
115 GpioMcuWrite( obj, value );
116 }
117
118 HAL_GPIO_Init( obj->port, &GPIO_InitStructure );
119 }
120 else
121 {
122 #if defined( BOARD_IOE_EXT )
123 // IOExt Pin
124 GpioIoeInit( obj, pin, mode, config, type, value );
125 #endif
126 }
127 }
128
GpioMcuSetContext(Gpio_t * obj,void * context)129 void GpioMcuSetContext( Gpio_t *obj, void* context )
130 {
131 obj->Context = context;
132 }
133
GpioMcuSetInterrupt(Gpio_t * obj,IrqModes irqMode,IrqPriorities irqPriority,GpioIrqHandler * irqHandler)134 void GpioMcuSetInterrupt( Gpio_t *obj, IrqModes irqMode, IrqPriorities irqPriority, GpioIrqHandler *irqHandler )
135 {
136 if( obj->pin < IOE_0 )
137 {
138 uint32_t priority = 0;
139
140 IRQn_Type IRQnb = EXTI0_IRQn;
141 GPIO_InitTypeDef GPIO_InitStructure;
142
143 if( irqHandler == NULL )
144 {
145 return;
146 }
147
148 obj->IrqHandler = irqHandler;
149
150 GPIO_InitStructure.Pin = obj->pinIndex;
151
152 if( irqMode == IRQ_RISING_EDGE )
153 {
154 GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING;
155 }
156 else if( irqMode == IRQ_FALLING_EDGE )
157 {
158 GPIO_InitStructure.Mode = GPIO_MODE_IT_FALLING;
159 }
160 else
161 {
162 GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING_FALLING;
163 }
164
165 GPIO_InitStructure.Pull = obj->pull;
166 GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
167
168 HAL_GPIO_Init( obj->port, &GPIO_InitStructure );
169
170 switch( irqPriority )
171 {
172 case IRQ_VERY_LOW_PRIORITY:
173 case IRQ_LOW_PRIORITY:
174 priority = 3;
175 break;
176 case IRQ_MEDIUM_PRIORITY:
177 priority = 2;
178 break;
179 case IRQ_HIGH_PRIORITY:
180 priority = 1;
181 break;
182 case IRQ_VERY_HIGH_PRIORITY:
183 default:
184 priority = 0;
185 break;
186 }
187
188 switch( obj->pinIndex )
189 {
190 case GPIO_PIN_0:
191 IRQnb = EXTI0_IRQn;
192 break;
193 case GPIO_PIN_1:
194 IRQnb = EXTI1_IRQn;
195 break;
196 case GPIO_PIN_2:
197 IRQnb = EXTI2_IRQn;
198 break;
199 case GPIO_PIN_3:
200 IRQnb = EXTI3_IRQn;
201 break;
202 case GPIO_PIN_4:
203 IRQnb = EXTI4_IRQn;
204 break;
205 case GPIO_PIN_5:
206 case GPIO_PIN_6:
207 case GPIO_PIN_7:
208 case GPIO_PIN_8:
209 case GPIO_PIN_9:
210 IRQnb = EXTI9_5_IRQn;
211 break;
212 case GPIO_PIN_10:
213 case GPIO_PIN_11:
214 case GPIO_PIN_12:
215 case GPIO_PIN_13:
216 case GPIO_PIN_14:
217 case GPIO_PIN_15:
218 IRQnb = EXTI15_10_IRQn;
219 break;
220 default:
221 break;
222 }
223
224 GpioIrq[( obj->pin ) & 0x0F] = obj;
225
226 HAL_NVIC_SetPriority( IRQnb , priority, 0 );
227 HAL_NVIC_EnableIRQ( IRQnb );
228 }
229 else
230 {
231 #if defined( BOARD_IOE_EXT )
232 // IOExt Pin
233 GpioIoeSetInterrupt( obj, irqMode, irqPriority, irqHandler );
234 #endif
235 }
236 }
237
GpioMcuRemoveInterrupt(Gpio_t * obj)238 void GpioMcuRemoveInterrupt( Gpio_t *obj )
239 {
240 if( obj->pin < IOE_0 )
241 {
242 // Clear callback before changing pin mode
243 GpioIrq[( obj->pin ) & 0x0F] = NULL;
244
245 GPIO_InitTypeDef GPIO_InitStructure;
246
247 GPIO_InitStructure.Pin = obj->pinIndex ;
248 GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
249 HAL_GPIO_Init( obj->port, &GPIO_InitStructure );
250 }
251 else
252 {
253 #if defined( BOARD_IOE_EXT )
254 // IOExt Pin
255 GpioIoeRemoveInterrupt( obj );
256 #endif
257 }
258 }
259
GpioMcuWrite(Gpio_t * obj,uint32_t value)260 void GpioMcuWrite( Gpio_t *obj, uint32_t value )
261 {
262 if( obj->pin < IOE_0 )
263 {
264 if( obj == NULL )
265 {
266 assert_param( LMN_STATUS_ERROR );
267 }
268 // Check if pin is not connected
269 if( obj->pin == NC )
270 {
271 return;
272 }
273 HAL_GPIO_WritePin( obj->port, obj->pinIndex , ( GPIO_PinState )value );
274 }
275 else
276 {
277 #if defined( BOARD_IOE_EXT )
278 // IOExt Pin
279 GpioIoeWrite( obj, value );
280 #endif
281 }
282 }
283
GpioMcuToggle(Gpio_t * obj)284 void GpioMcuToggle( Gpio_t *obj )
285 {
286 if( obj->pin < IOE_0 )
287 {
288 if( obj == NULL )
289 {
290 assert_param( LMN_STATUS_ERROR );
291 }
292
293 // Check if pin is not connected
294 if( obj->pin == NC )
295 {
296 return;
297 }
298 HAL_GPIO_TogglePin( obj->port, obj->pinIndex );
299 }
300 else
301 {
302 #if defined( BOARD_IOE_EXT )
303 // IOExt Pin
304 GpioIoeToggle( obj );
305 #endif
306 }
307 }
308
GpioMcuRead(Gpio_t * obj)309 uint32_t GpioMcuRead( Gpio_t *obj )
310 {
311 if( obj->pin < IOE_0 )
312 {
313 if( obj == NULL )
314 {
315 assert_param( LMN_STATUS_ERROR );
316 }
317 // Check if pin is not connected
318 if( obj->pin == NC )
319 {
320 return 0;
321 }
322 return HAL_GPIO_ReadPin( obj->port, obj->pinIndex );
323 }
324 else
325 {
326 #if defined( BOARD_IOE_EXT )
327 // IOExt Pin
328 return GpioIoeRead( obj );
329 #else
330 return 0;
331 #endif
332 }
333 }
334
EXTI0_IRQHandler(void)335 void EXTI0_IRQHandler( void )
336 {
337 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_0 );
338 }
339
EXTI1_IRQHandler(void)340 void EXTI1_IRQHandler( void )
341 {
342 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_1 );
343 }
344
EXTI2_IRQHandler(void)345 void EXTI2_IRQHandler( void )
346 {
347 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_2 );
348 }
349
EXTI3_IRQHandler(void)350 void EXTI3_IRQHandler( void )
351 {
352 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_3 );
353 }
354
EXTI4_IRQHandler(void)355 void EXTI4_IRQHandler( void )
356 {
357 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_4 );
358 }
359
EXTI9_5_IRQHandler(void)360 void EXTI9_5_IRQHandler( void )
361 {
362 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_5 );
363 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_6 );
364 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_7 );
365 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_8 );
366 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_9 );
367 }
368
EXTI15_10_IRQHandler(void)369 void EXTI15_10_IRQHandler( void )
370 {
371 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_10 );
372 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_11 );
373 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_12 );
374 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_13 );
375 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_14 );
376 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_15 );
377 }
378
HAL_GPIO_EXTI_Callback(uint16_t gpioPin)379 void HAL_GPIO_EXTI_Callback( uint16_t gpioPin )
380 {
381 uint8_t callbackIndex = 0;
382
383 if( gpioPin > 0 )
384 {
385 while( gpioPin != 0x01 )
386 {
387 gpioPin = gpioPin >> 1;
388 callbackIndex++;
389 }
390 }
391
392 if( ( GpioIrq[callbackIndex] != NULL ) && ( GpioIrq[callbackIndex]->IrqHandler != NULL ) )
393 {
394 GpioIrq[callbackIndex]->IrqHandler( GpioIrq[callbackIndex]->Context );
395 }
396 }
397