GCC Code Coverage Report


Directory: src/drv/
File: src/drv/gpio/src/gpio_driver.c
Date: 2024-01-25 15:03:18
Exec Total Coverage
Lines: 0 116 0.0%
Branches: 0 88 0.0%

Line Branch Exec Source
1 /********************************************************************************************************//**
2 * @file gpio_driver.c
3 *
4 * @brief File containing the APIs for configuring the GPIO peripheral.
5 *
6 * Public Functions:
7 * - void GPIO_Init(GPIO_Handle_t* pGPIOHandle)
8 * - void GPIO_DeInit(GPIO_RegDef_t* pGPIOx)
9 * - void GPIO_PerClkCtrl(GPIO_RegDef_t* pGPIOx, uint8_t en_or_di)
10 * - uint8_t GPIO_ReadFromInputPin(GPIO_RegDef_t* pGPIOx, uint8_t pin_number)
11 * - uint16_t GPIO_ReadFromInputPort(GPIO_RegDef_t* pGPIOx)
12 * - void GPIO_WriteToOutputPin(GPIO_RegDef_t* pGPIOx, uint8_t pin_number, uint8_t value)
13 * - void GPIO_WriteToOutputPort(GPIO_RegDef_t* pGPIOx, uint16_t value)
14 * - void GPIO_ToggleOutputPin(GPIO_RegDef_t* pGPIOx, uint8_t pin_number)
15 * - void GPIO_IRQHandling(uint8_t pin_number)
16 *
17 * @note
18 * For further information about functions refer to the corresponding header file.
19 */
20
21 #include <stdint.h>
22 #include "gpio_driver.h"
23
24 /***********************************************************************************************************/
25 /* Public API Definitions */
26 /***********************************************************************************************************/
27
28 void GPIO_Init(GPIO_Handle_t* pGPIOHandle){
29
30 uint32_t temp = 0;
31 uint8_t temp1, temp2 = 0;
32 uint8_t portcode = 0;
33
34 /* Enable the peripheral clock */
35 GPIO_PerClkCtrl(pGPIOHandle->pGPIOx, ENABLE);
36
37 /* Configure the mode */
38 if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode <= GPIO_MODE_ANALOG){
39 /* Non-interrupt mode */
40 temp = (pGPIOHandle->GPIO_PinConfig.GPIO_PinMode << (2*pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
41 pGPIOHandle->pGPIOx->MODER &= ~(0x3 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); /* clearing */
42 pGPIOHandle->pGPIOx->MODER |= temp; /* setting */
43 }
44 else{
45 /* Interrupt mode */
46 if((pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_IT_FT) ||
47 (pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_EV_FT)){
48 /* Configure the FTSR */
49 EXTI->FTSR |= (1 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
50 /* Clear the corresponding RTSR bit */
51 EXTI->RTSR &= ~(1 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
52 }
53 else if((pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_IT_RT) ||
54 (pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_EV_RT)){
55 /* Configure the RTSR */
56 EXTI->RTSR |= (1 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
57 /* Clear the corresponding FTSR bit */
58 EXTI->FTSR &= ~(1 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
59 }
60 else if((pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_IT_RFT) ||
61 (pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_EV_RFT)){
62 /* Configure both the FTSR and RTSR */
63 EXTI->RTSR |= (1 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
64 EXTI->FTSR |= (1 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
65 }
66
67 /* Configure the GPIO port selection in SYSCFG_EXTICR */
68 temp1 = pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber / 4;
69 temp2 = pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber % 4;
70 portcode = GPIO_BASEADDR_TO_CODE(pGPIOHandle->pGPIOx);
71 SYSCFG_PCLK_EN();
72 SYSCFG->EXTICR[temp1] = portcode << (temp2*4);
73
74 if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode <= GPIO_MODE_IT_RFT){
75 /* Enable the EXTI interrupt delivery using IMR */
76 EXTI->IMR |= (1 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
77 }
78 else{
79 /* Enable the EXTI event delivery using EMR */
80 EXTI->EMR |= (1 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
81 }
82 }
83
84 temp = 0;
85
86 /* Configure the speed */
87 temp = (pGPIOHandle->GPIO_PinConfig.GPIO_PinSpeed << (2*pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
88 pGPIOHandle->pGPIOx->OSPEEDER &= ~(0x3 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); /* clearing */
89 pGPIOHandle->pGPIOx->OSPEEDER |= temp; /* setting */
90 temp = 0;
91
92 /* Configure the pupd settings */
93 temp = (pGPIOHandle->GPIO_PinConfig.GPIO_PinPuPdControl <<
94 (2*pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
95 pGPIOHandle->pGPIOx->PUPDR &= ~(0x3 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); /* clearing */
96 pGPIOHandle->pGPIOx->PUPDR |= temp; /* setting */
97 temp = 0;
98
99 /* Configure the optype */
100 temp = (pGPIOHandle->GPIO_PinConfig.GPIO_PinOPType << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
101 pGPIOHandle->pGPIOx->OTYPER &= ~(0x1 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); /* clearing */
102 pGPIOHandle->pGPIOx->OTYPER |= temp; /* setting */
103 temp = 0;
104
105 /* Configure the alternate functionality */
106 if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_ALTFN){
107
108 temp1 = pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber / 8;
109 temp2 = pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber % 8;
110 pGPIOHandle->pGPIOx->AFR[temp1] &= ~(0xF << (4*temp2));
111 pGPIOHandle->pGPIOx->AFR[temp1] |= (pGPIOHandle->GPIO_PinConfig.GPIO_PinAltFunMode << (4*temp2));
112 }
113 }
114
115 void GPIO_DeInit(GPIO_RegDef_t* pGPIOx){
116
117 if(pGPIOx == GPIOA){
118 GPIOA_REG_RESET();
119 }
120 else if(pGPIOx == GPIOB){
121 GPIOB_REG_RESET();
122 }
123 else if(pGPIOx == GPIOC){
124 GPIOC_REG_RESET();
125 }
126 else if(pGPIOx == GPIOD){
127 GPIOD_REG_RESET();
128 }
129 else if(pGPIOx == GPIOE){
130 GPIOE_REG_RESET();
131 }
132 else if(pGPIOx == GPIOF){
133 GPIOF_REG_RESET();
134 }
135 else if(pGPIOx == GPIOG){
136 GPIOG_REG_RESET();
137 }
138 else if(pGPIOx == GPIOH){
139 GPIOH_REG_RESET();
140 }
141 else{
142 /* do nothing */
143 }
144 }
145
146 void GPIO_PerClkCtrl(GPIO_RegDef_t* pGPIOx, uint8_t en_or_di){
147
148 if(en_or_di == ENABLE){
149 if(pGPIOx == GPIOA){
150 GPIOA_PCLK_EN();
151 }
152 else if(pGPIOx == GPIOB){
153 GPIOB_PCLK_EN();
154 }
155 else if(pGPIOx == GPIOC){
156 GPIOC_PCLK_EN();
157 }
158 else if(pGPIOx == GPIOD){
159 GPIOD_PCLK_EN();
160 }
161 else if(pGPIOx == GPIOE){
162 GPIOE_PCLK_EN();
163 }
164 else if(pGPIOx == GPIOF){
165 GPIOF_PCLK_EN();
166 }
167 else if(pGPIOx == GPIOG){
168 GPIOG_PCLK_EN();
169 }
170 else if(pGPIOx == GPIOH){
171 GPIOH_PCLK_EN();
172 }
173 else{
174 /* do nothing */
175 }
176 }
177 else{
178 if(pGPIOx == GPIOA){
179 GPIOA_PCLK_DI();
180 }
181 else if(pGPIOx == GPIOB){
182 GPIOB_PCLK_DI();
183 }
184 else if(pGPIOx == GPIOC){
185 GPIOC_PCLK_DI();
186 }
187 else if(pGPIOx == GPIOD){
188 GPIOD_PCLK_DI();
189 }
190 else if(pGPIOx == GPIOE){
191 GPIOE_PCLK_DI();
192 }
193 else if(pGPIOx == GPIOF){
194 GPIOF_PCLK_DI();
195 }
196 else if(pGPIOx == GPIOG){
197 GPIOG_PCLK_DI();
198 }
199 else if(pGPIOx == GPIOH){
200 GPIOH_PCLK_DI();
201 }
202 else{
203 /* do nothing */
204 }
205 }
206 }
207
208 uint8_t GPIO_ReadFromInputPin(GPIO_RegDef_t* pGPIOx, uint8_t pin_number){
209
210 uint8_t value;
211 value = (uint8_t)((pGPIOx->IDR >> pin_number) & 0x00000001);
212
213 return value;
214 }
215
216 uint16_t GPIO_ReadFromInputPort(GPIO_RegDef_t* pGPIOx){
217
218 uint16_t value;
219 value = (uint16_t)pGPIOx->IDR;
220
221 return value;
222 }
223
224 void GPIO_WriteToOutputPin(GPIO_RegDef_t* pGPIOx, uint8_t pin_number, uint8_t value){
225
226 if(value == GPIO_PIN_SET){
227 pGPIOx->ODR |= (1 << pin_number);
228 }
229 else{
230 pGPIOx->ODR &= ~(1 << pin_number);
231 }
232 }
233
234 void GPIO_WriteToOutputPort(GPIO_RegDef_t* pGPIOx, uint16_t value){
235
236 pGPIOx->ODR = value;
237 }
238
239 void GPIO_ToggleOutputPin(GPIO_RegDef_t* pGPIOx, uint8_t pin_number){
240 pGPIOx->ODR ^= (1 << pin_number);
241 }
242
243 void GPIO_IRQHandling(uint8_t pin_number){
244 /* Clear the EXTI PR register corresponding to the pin_number */
245 if(EXTI->PR & (1 << pin_number)){
246 /* clear */
247 EXTI->PR |= (1 << pin_number);
248 }
249 }
250