1 ////////////////////////////////////////////////////////////////////////////////
2 /// @file     hal_gpio.c
3 /// @author   AE TEAM
4 /// @brief    THIS FILE PROVIDES ALL THE GPIO FIRMWARE FUNCTIONS.
5 ////////////////////////////////////////////////////////////////////////////////
6 /// @attention
7 ///
8 /// THE EXISTING FIRMWARE IS ONLY FOR REFERENCE, WHICH IS DESIGNED TO PROVIDE
9 /// CUSTOMERS WITH CODING INFORMATION ABOUT THEIR PRODUCTS SO THEY CAN SAVE
10 /// TIME. THEREFORE, MINDMOTION SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR
11 /// CONSEQUENTIAL DAMAGES ABOUT ANY CLAIMS ARISING OUT OF THE CONTENT OF SUCH
12 /// HARDWARE AND/OR THE USE OF THE CODING INFORMATION CONTAINED HEREIN IN
13 /// CONNECTION WITH PRODUCTS MADE BY CUSTOMERS.
14 ///
15 /// <H2><CENTER>&COPY; COPYRIGHT MINDMOTION </CENTER></H2>
16 ////////////////////////////////////////////////////////////////////////////////
17 
18 // Define to prevent recursive inclusion
19 #define _HAL_GPIO_C_
20 
21 // Files includes
22 #include "reg_exti.h"
23 #include "hal_rcc.h"
24 #include "hal_gpio.h"
25 
26 
27 
28 
29 ////////////////////////////////////////////////////////////////////////////////
30 /// @addtogroup MM32_Hardware_Abstract_Layer
31 /// @{
32 
33 ////////////////////////////////////////////////////////////////////////////////
34 /// @addtogroup GPIO_HAL
35 /// @{
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 /// @addtogroup GPIO_Exported_Functions
39 /// @{
40 
41 ////////////////////////////////////////////////////////////////////////////////
42 /// @brief  Deinitializes the gpio peripheral registers to their default reset
43 ///         values.
44 /// @param  gpio: select the GPIO peripheral.
45 /// @retval None.
46 ////////////////////////////////////////////////////////////////////////////////
GPIO_DeInit(GPIO_TypeDef * gpio)47 void GPIO_DeInit(GPIO_TypeDef* gpio)
48 {
49     switch (*(vu32*)&gpio) {
50         case (u32)GPIOA:
51             RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, DISABLE);
52             break;
53         case (u32)GPIOB:
54             RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOB, DISABLE);
55             break;
56         case (u32)GPIOC:
57             RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOC, DISABLE);
58             break;
59         case (u32)GPIOD:
60             RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOD, DISABLE);
61             break;
62         case (u32)GPIOE:
63             RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOE, DISABLE);
64             break;
65         default:
66             break;
67     }
68 }
69 
70 ////////////////////////////////////////////////////////////////////////////////
71 /// @brief  Deinitializes the Alternate Functions (remap, event control
72 ///         and EXTI configuration) registers to their default reset values.
73 /// @param  None.
74 /// @retval None.
75 ////////////////////////////////////////////////////////////////////////////////
GPIO_AFIODeInit()76 void GPIO_AFIODeInit()
77 {
78     GPIOA->AFRL = 0xFFFFFFFF;
79     GPIOA->AFRH = 0xF00FFFFF;       //  PA14:SWCLK, PA13:PSWDIO
80     GPIOB->AFRL = 0xFFFFFFFF;
81     GPIOB->AFRH = 0xFFFFFFFF;
82     GPIOC->AFRL = 0xFFFFFFFF;
83     GPIOC->AFRH = 0xFFFFFFFF;
84     GPIOD->AFRL = 0xFFFFFFFF;
85     GPIOD->AFRH = 0xFFFFFFFF;
86     GPIOE->AFRL = 0xFFFFFFFF;
87     GPIOE->AFRH = 0xFFFFFFFF;
88 }
89 
90 ////////////////////////////////////////////////////////////////////////////////
91 /// @brief  Initializes the gpio peripheral according to the specified
92 ///         parameters in the init_struct.
93 /// @param  gpio: select the GPIO peripheral.
94 /// @param  init_struct: pointer to a GPIO_InitTypeDef structure that
95 ///         contains the configuration information for the specified GPIO
96 ///         peripheral.
97 /// @retval None.
98 ////////////////////////////////////////////////////////////////////////////////
GPIO_Init(GPIO_TypeDef * gpio,GPIO_InitTypeDef * init_struct)99 void GPIO_Init(GPIO_TypeDef* gpio, GPIO_InitTypeDef* init_struct)
100 {
101     u8   idx;
102     u8 i;
103     u32 tmp;
104     __IO u32* reg ;
105 
106     // 1x
107     u32 dat = init_struct->GPIO_Mode & 0x0F;
108     if (init_struct->GPIO_Mode & 0x10)
109         dat |= init_struct->GPIO_Speed;
110 
111     // 0x
112     reg  = &gpio->CRL;
113     for (i = 0; i < 8; i++) {
114         idx = i * 4;
115         if ((init_struct->GPIO_Pin) & (1 << i)) {
116             *reg  = (*reg  & ~(0xF << idx)) | (dat << idx);
117         }
118     }
119 
120     reg     = &gpio->CRH;
121     tmp = init_struct->GPIO_Pin >> 8;
122     for (i = 0; i < 8; i++) {
123         idx = i * 4;
124         if (tmp & (1 << i)) {
125             *reg  = (*reg  & ~(0xF << idx)) | (dat << idx);
126         }
127     }
128 
129     // 2x,4x
130     if (init_struct->GPIO_Mode == GPIO_Mode_IPD)
131         gpio->BRR |= init_struct->GPIO_Pin;
132     else if (init_struct->GPIO_Mode == GPIO_Mode_IPU)
133         gpio->BSRR |= init_struct->GPIO_Pin;
134 }
135 ////////////////////////////////////////////////////////////////////////////////
136 /// @brief  Fills each init_struct member with its default value.
137 /// @param init_struct : pointer to a GPIO_InitTypeDef structure
138 ///   which will be initialized.
139 /// @retval : None
140 ////////////////////////////////////////////////////////////////////////////////
GPIO_StructInit(GPIO_InitTypeDef * init_struct)141 void GPIO_StructInit(GPIO_InitTypeDef* init_struct)
142 {
143     // Reset GPIO init structure parameters values
144     init_struct->GPIO_Pin  = GPIO_Pin_All;
145     init_struct->GPIO_Speed = GPIO_Speed_2MHz;
146     init_struct->GPIO_Mode = GPIO_Mode_FLOATING;
147 }
148 ////////////////////////////////////////////////////////////////////////////////
149 /// @brief  Reads the input data of specified GPIO port pin.
150 /// @param  gpio:  select the GPIO peripheral.
151 /// @param  pin:  specifies the port pin to be read.
152 ///         This parameter can be GPIO_Pin_x where x can be (0..15).
153 /// @retval The input port pin value.
154 ////////////////////////////////////////////////////////////////////////////////
GPIO_ReadInputDataBit(GPIO_TypeDef * gpio,u16 pin)155 bool GPIO_ReadInputDataBit(GPIO_TypeDef* gpio, u16 pin)
156 {
157     return ((gpio->IDR & pin)) ? Bit_SET : Bit_RESET;
158 }
159 
160 ////////////////////////////////////////////////////////////////////////////////
161 /// @brief  Reads all GPIO port pins input data.
162 /// @param  gpio: select the GPIO peripheral.
163 /// @retval GPIO port input data value.
164 ////////////////////////////////////////////////////////////////////////////////
GPIO_ReadInputData(GPIO_TypeDef * gpio)165 u16 GPIO_ReadInputData(GPIO_TypeDef* gpio)
166 {
167     return gpio->IDR;
168 }
169 
170 ////////////////////////////////////////////////////////////////////////////////
171 /// @brief  Reads the output data of specified GPIO port pin.
172 /// @param  gpio: select the GPIO peripheral.
173 /// @param  pin:  specifies the port bit to be read.
174 ///         This parameter can be GPIO_Pin_x where x can be (0..15).
175 /// @retval The output port pin value.
176 ////////////////////////////////////////////////////////////////////////////////
GPIO_ReadOutputDataBit(GPIO_TypeDef * gpio,u16 pin)177 bool GPIO_ReadOutputDataBit(GPIO_TypeDef* gpio, u16 pin)
178 {
179     return (gpio->ODR & pin) ? Bit_SET : Bit_RESET;
180 }
181 
182 ////////////////////////////////////////////////////////////////////////////////
183 /// @brief  Reads all GPIO port pins output data.
184 /// @param  gpio: select the GPIO peripheral.
185 /// @retval GPIO port output data value.
186 ////////////////////////////////////////////////////////////////////////////////
GPIO_ReadOutputData(GPIO_TypeDef * gpio)187 u16 GPIO_ReadOutputData(GPIO_TypeDef* gpio)
188 {
189     return gpio->ODR;
190 }
191 
192 ////////////////////////////////////////////////////////////////////////////////
193 /// @brief  Sets the selected GPIO port pin.
194 /// @param  gpio: where x can be (A..D) to select the GPIO peripheral.
195 /// @param  pin: specifies the port pins to be written.
196 ///         This parameter can be any combination of GPIO_Pin_x where x can be
197 ///         (0..15).
198 /// @retval None.
199 ////////////////////////////////////////////////////////////////////////////////
GPIO_SetBits(GPIO_TypeDef * gpio,u16 pin)200 void GPIO_SetBits(GPIO_TypeDef* gpio, u16 pin)
201 {
202     gpio->BSRR = pin;
203 }
204 
205 ////////////////////////////////////////////////////////////////////////////////
206 /// @brief  Clears the selected GPIO port bit.
207 /// @param  gpio: where x can be (A..D) to select the GPIO peripheral.
208 /// @param  pin: specifies the port pins to be written.
209 ///         This parameter can be any combination of GPIO_Pin_x where x can be
210 ///         (0..15).
211 /// @retval None.
212 ////////////////////////////////////////////////////////////////////////////////
GPIO_ResetBits(GPIO_TypeDef * gpio,u16 pin)213 void GPIO_ResetBits(GPIO_TypeDef* gpio, u16 pin)
214 {
215     gpio->BRR = pin;
216 }
217 
218 ////////////////////////////////////////////////////////////////////////////////
219 /// @brief  Sets or clears the selected GPIO port pin.
220 /// @param  gpio: select the GPIO peripheral.
221 /// @param  pin: specifies the port bit to be written.
222 ///         This parameter can be one of GPIO_Pin_x where x can be (0..15).
223 /// @param  value: specifies the value to be written to the selected bit.
224 ///         This parameter can be one of the BitAction enum values:
225 /// @arg    Bit_RESET: to clear the port pin
226 /// @arg    Bit_SET: to set the port pin
227 /// @retval None.
228 ////////////////////////////////////////////////////////////////////////////////
GPIO_WriteBit(GPIO_TypeDef * gpio,u16 pin,BitAction value)229 void GPIO_WriteBit(GPIO_TypeDef* gpio, u16 pin, BitAction value)
230 {
231     (value) ? (gpio->BSRR = pin) : (gpio->BRR = pin);
232 }
233 
234 ////////////////////////////////////////////////////////////////////////////////
235 /// @brief  Writes data to all GPIO port pins.
236 /// @param  gpio: where x can be (A..D) to select the GPIO peripheral.
237 /// @param  value: specifies the value to be written to the port output data
238 ///         register.
239 /// @retval None.
240 ////////////////////////////////////////////////////////////////////////////////
GPIO_Write(GPIO_TypeDef * gpio,u16 value)241 void GPIO_Write(GPIO_TypeDef* gpio, u16 value)
242 {
243     gpio->ODR = value;
244 }
245 
246 ////////////////////////////////////////////////////////////////////////////////
247 /// @brief  Locks GPIO Pins configuration.
248 /// @param  gpio: to select the GPIO peripheral.
249 /// @param  pin: specifies the port bit to be written.
250 ///         This parameter can be any combination of GPIO_Pin_x where x can be
251 ///         (0..15).
252 /// @param  state: new lock state of the port pin.
253 ///         This parameter can be: ENABLE or DISABLE.
254 /// @retval None.
255 ////////////////////////////////////////////////////////////////////////////////
GPIO_PinLock(GPIO_TypeDef * gpio,u16 pin,FunctionalState state)256 void GPIO_PinLock(GPIO_TypeDef* gpio, u16 pin, FunctionalState state)
257 {
258     (state) ? (gpio->LCKR |= pin) : (gpio->LCKR &= ~pin);
259 }
260 
261 ////////////////////////////////////////////////////////////////////////////////
262 /// @brief  Locks GPIO Pins configuration registers until next system reset.
263 /// @param  gpio: to select the GPIO peripheral.
264 /// @param  pin: specifies the port bit to be written.
265 ///         This parameter can be any combination of GPIO_Pin_x where x can be
266 ///         (0..15).
267 /// @retval None.
268 ////////////////////////////////////////////////////////////////////////////////
GPIO_PinLockConfig(GPIO_TypeDef * gpio,u16 pin)269 void GPIO_PinLockConfig(GPIO_TypeDef* gpio, u16 pin)
270 {
271     gpio->LCKR = GPIO_LCKR_LCKK | pin;
272     gpio->LCKR = pin;
273     gpio->LCKR = GPIO_LCKR_LCKK | pin;
274     gpio->LCKR;
275     gpio->LCKR;
276 }
277 
278 ////////////////////////////////////////////////////////////////////////////////
279 /// @brief  Enables or disables the port pin remapping.
280 /// @param  remap: selects the pin to remap.
281 /// @param  mask: the corresponding remapping mask of the remapping pin.
282 /// @param  state: new state of the port pin remapping.
283 ///         This parameter can be: ENABLE or DISABLE.
284 /// @retval None.
285 ////////////////////////////////////////////////////////////////////////////////
286 
287 ////////////////////////////////////////////////////////////////////////////////
288 /// @brief  Writes data to the specified GPIO data port.
289 /// @param  gpio: select the GPIO peripheral.
290 /// @param  pin: specifies the pin for the Alternate function.
291 ///         This parameter can be GPIO_PinSourcex where x can be (0..15) for
292 ///         GPIOA, GPIOB, GPIOD and (0..12) for GPIOC .
293 /// @param  alternate_function: selects the pin to used as Alternate function.
294 ///         This parameter can be the GPIO_AF_x where x can be (0..7).
295 /// @note   The pin should be used for Digital IP.
296 /// @retval None.
297 ////////////////////////////////////////////////////////////////////////////////
GPIO_PinAFConfig(GPIO_TypeDef * gpio,u8 pin,u8 alternate_function)298 void GPIO_PinAFConfig(GPIO_TypeDef* gpio, u8 pin, u8 alternate_function)
299 {
300     u8 shift = (pin & 0x07) * 4;
301     u32* ptr = (pin < 8) ? (u32*)&gpio->AFRL : (u32*)&gpio->AFRH;
302     *ptr = (*ptr & ~(0x0F << shift)) | (alternate_function << shift);
303 }
304 
305 ////////////////////////////////////////////////////////////////////////////////
306 /// @brief  Set the remap function and AF function of the GPIO pin.
307 /// @param  gpio:select the GPIO peripheral.
308 /// @param  pin: specifies the pin for the Alternate function.
309 ///         This parameter can be GPIO_Pin_x where x can be (0..15) for
310 ///         GPIOA, GPIOB, GPIOD and (0..12) for GPIOC .
311 /// @param  remap: selects the pin to remap.
312 /// @param  alternate_function: selects the pin to used as Alternate function.
313 ///         This parameter can be the GPIO_AF_x where x can be (0..7).
314 /// @note   The pin should be used for Digital IP.
315 /// @retval None.
316 ////////////////////////////////////////////////////////////////////////////////
exGPIO_PinAFConfig(GPIO_TypeDef * gpio,u16 pin,s32 remap,s8 alternate_function)317 void exGPIO_PinAFConfig(GPIO_TypeDef* gpio, u16 pin, s32 remap, s8 alternate_function)
318 {
319     u8 i;
320     u8 shift;
321     u32* ptr;
322 
323     if (alternate_function >= 0) {
324         for (i = 0; i < 32; i++) {
325             if (pin & 0x01) {
326                 pin = i;
327                 break;
328             }
329             pin >>= 1;
330         }
331 
332         shift = (pin & 0x07) * 4;
333         ptr = (pin < 8) ? (u32*)&gpio->AFRL : (u32*)&gpio->AFRH;
334         *ptr = (*ptr & ~(0x0F << shift)) | (alternate_function << shift);
335     }
336 }
337 
338 
339 /// @}
340 
341 /// @}
342 
343 /// @}
344 
345