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 "stm32l0xx.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 assert_param( LMN_STATUS_ERROR );
73 }
74
75 GPIO_InitStructure.Pin = obj->pinIndex ;
76 GPIO_InitStructure.Pull = obj->pull = type;
77 GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
78
79 if( mode == PIN_INPUT )
80 {
81 GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
82 }
83 else if( mode == PIN_ANALOGIC )
84 {
85 GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
86 }
87 else if( mode == PIN_ALTERNATE_FCT )
88 {
89 if( config == PIN_OPEN_DRAIN )
90 {
91 GPIO_InitStructure.Mode = GPIO_MODE_AF_OD;
92 }
93 else
94 {
95 GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
96 }
97 GPIO_InitStructure.Alternate = value;
98 }
99 else // mode output
100 {
101 if( config == PIN_OPEN_DRAIN )
102 {
103 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
104 }
105 else
106 {
107 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
108 }
109 }
110
111 // Sets initial output value
112 if( mode == PIN_OUTPUT )
113 {
114 GpioMcuWrite( obj, value );
115 }
116
117 HAL_GPIO_Init( obj->port, &GPIO_InitStructure );
118 }
119 else
120 {
121 #if defined( BOARD_IOE_EXT )
122 // IOExt Pin
123 GpioIoeInit( obj, pin, mode, config, type, value );
124 #endif
125 }
126 }
127
GpioMcuSetContext(Gpio_t * obj,void * context)128 void GpioMcuSetContext( Gpio_t *obj, void* context )
129 {
130 obj->Context = context;
131 }
132
GpioMcuSetInterrupt(Gpio_t * obj,IrqModes irqMode,IrqPriorities irqPriority,GpioIrqHandler * irqHandler)133 void GpioMcuSetInterrupt( Gpio_t *obj, IrqModes irqMode, IrqPriorities irqPriority, GpioIrqHandler *irqHandler )
134 {
135 if( obj->pin < IOE_0 )
136 {
137 uint32_t priority = 0;
138
139 IRQn_Type IRQnb = EXTI0_1_IRQn;
140 GPIO_InitTypeDef GPIO_InitStructure;
141
142 if( irqHandler == NULL )
143 {
144 return;
145 }
146
147 obj->IrqHandler = irqHandler;
148
149 GPIO_InitStructure.Pin = obj->pinIndex;
150
151 if( irqMode == IRQ_RISING_EDGE )
152 {
153 GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING;
154 }
155 else if( irqMode == IRQ_FALLING_EDGE )
156 {
157 GPIO_InitStructure.Mode = GPIO_MODE_IT_FALLING;
158 }
159 else
160 {
161 GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING_FALLING;
162 }
163
164 GPIO_InitStructure.Pull = obj->pull;
165 GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
166
167 HAL_GPIO_Init( obj->port, &GPIO_InitStructure );
168
169 switch( irqPriority )
170 {
171 case IRQ_VERY_LOW_PRIORITY:
172 case IRQ_LOW_PRIORITY:
173 priority = 3;
174 break;
175 case IRQ_MEDIUM_PRIORITY:
176 priority = 2;
177 break;
178 case IRQ_HIGH_PRIORITY:
179 priority = 1;
180 break;
181 case IRQ_VERY_HIGH_PRIORITY:
182 default:
183 priority = 0;
184 break;
185 }
186
187 switch( obj->pinIndex )
188 {
189 case GPIO_PIN_0:
190 case GPIO_PIN_1:
191 IRQnb = EXTI0_1_IRQn;
192 break;
193 case GPIO_PIN_2:
194 case GPIO_PIN_3:
195 IRQnb = EXTI2_3_IRQn;
196 break;
197 case GPIO_PIN_4:
198 case GPIO_PIN_5:
199 case GPIO_PIN_6:
200 case GPIO_PIN_7:
201 case GPIO_PIN_8:
202 case GPIO_PIN_9:
203 case GPIO_PIN_10:
204 case GPIO_PIN_11:
205 case GPIO_PIN_12:
206 case GPIO_PIN_13:
207 case GPIO_PIN_14:
208 case GPIO_PIN_15:
209 IRQnb = EXTI4_15_IRQn;
210 break;
211 default:
212 break;
213 }
214
215 GpioIrq[( obj->pin ) & 0x0F] = obj;
216
217 HAL_NVIC_SetPriority( IRQnb , priority, 0 );
218 HAL_NVIC_EnableIRQ( IRQnb );
219 }
220 else
221 {
222 #if defined( BOARD_IOE_EXT )
223 // IOExt Pin
224 GpioIoeSetInterrupt( obj, irqMode, irqPriority, irqHandler );
225 #endif
226 }
227 }
228
GpioMcuRemoveInterrupt(Gpio_t * obj)229 void GpioMcuRemoveInterrupt( Gpio_t *obj )
230 {
231 if( obj->pin < IOE_0 )
232 {
233 // Clear callback before changing pin mode
234 GpioIrq[( obj->pin ) & 0x0F] = NULL;
235
236 GPIO_InitTypeDef GPIO_InitStructure;
237
238 GPIO_InitStructure.Pin = obj->pinIndex ;
239 GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
240 HAL_GPIO_Init( obj->port, &GPIO_InitStructure );
241 }
242 else
243 {
244 #if defined( BOARD_IOE_EXT )
245 // IOExt Pin
246 GpioIoeRemoveInterrupt( obj );
247 #endif
248 }
249 }
250
GpioMcuWrite(Gpio_t * obj,uint32_t value)251 void GpioMcuWrite( Gpio_t *obj, uint32_t value )
252 {
253 if( obj->pin < IOE_0 )
254 {
255 if( obj == NULL )
256 {
257 assert_param( LMN_STATUS_ERROR );
258 }
259 // Check if pin is not connected
260 if( obj->pin == NC )
261 {
262 return;
263 }
264 HAL_GPIO_WritePin( obj->port, obj->pinIndex , ( GPIO_PinState )value );
265 }
266 else
267 {
268 #if defined( BOARD_IOE_EXT )
269 // IOExt Pin
270 GpioIoeWrite( obj, value );
271 #endif
272 }
273 }
274
GpioMcuToggle(Gpio_t * obj)275 void GpioMcuToggle( Gpio_t *obj )
276 {
277 if( obj->pin < IOE_0 )
278 {
279 if( obj == NULL )
280 {
281 assert_param( LMN_STATUS_ERROR );
282 }
283
284 // Check if pin is not connected
285 if( obj->pin == NC )
286 {
287 return;
288 }
289 HAL_GPIO_TogglePin( obj->port, obj->pinIndex );
290 }
291 else
292 {
293 #if defined( BOARD_IOE_EXT )
294 // IOExt Pin
295 GpioIoeToggle( obj );
296 #endif
297 }
298 }
299
GpioMcuRead(Gpio_t * obj)300 uint32_t GpioMcuRead( Gpio_t *obj )
301 {
302 if( obj->pin < IOE_0 )
303 {
304 if( obj == NULL )
305 {
306 assert_param( LMN_STATUS_ERROR );
307 }
308 // Check if pin is not connected
309 if( obj->pin == NC )
310 {
311 return 0;
312 }
313 return HAL_GPIO_ReadPin( obj->port, obj->pinIndex );
314 }
315 else
316 {
317 #if defined( BOARD_IOE_EXT )
318 // IOExt Pin
319 return GpioIoeRead( obj );
320 #else
321 return 0;
322 #endif
323 }
324 }
325
EXTI0_1_IRQHandler(void)326 void EXTI0_1_IRQHandler( void )
327 {
328 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_0 );
329 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_1 );
330 }
331
EXTI2_3_IRQHandler(void)332 void EXTI2_3_IRQHandler( void )
333 {
334 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_2 );
335 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_3 );
336 }
337
EXTI4_15_IRQHandler(void)338 void EXTI4_15_IRQHandler( void )
339 {
340 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_4 );
341 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_5 );
342 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_6 );
343 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_7 );
344 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_8 );
345 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_9 );
346 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_10 );
347 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_11 );
348 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_12 );
349 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_13 );
350 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_14 );
351 HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_15 );
352 }
353
HAL_GPIO_EXTI_Callback(uint16_t gpioPin)354 void HAL_GPIO_EXTI_Callback( uint16_t gpioPin )
355 {
356 uint8_t callbackIndex = 0;
357
358 if( gpioPin > 0 )
359 {
360 while( gpioPin != 0x01 )
361 {
362 gpioPin = gpioPin >> 1;
363 callbackIndex++;
364 }
365 }
366
367 if( ( GpioIrq[callbackIndex] != NULL ) && ( GpioIrq[callbackIndex]->IrqHandler != NULL ) )
368 {
369 GpioIrq[callbackIndex]->IrqHandler( GpioIrq[callbackIndex]->Context );
370 }
371 }
372