Made gpio API completely platform independent

This commit is contained in:
Silvano Seva 2020-10-22 23:06:07 +02:00 committed by Niccolò Izzo
parent ddc79bcf0c
commit 9b20e5010c
3 changed files with 59 additions and 55 deletions

View File

@ -19,7 +19,6 @@
#define GPIO_H
#include <stdint.h>
#include "stm32f4xx.h"
/**
* GPIO functional modes.
@ -55,7 +54,7 @@ enum Speed
* @param pin: GPIO pin number, between 0 and 15.
* @param mode: GPIO functional mode to be set.
*/
void gpio_setMode(GPIO_TypeDef *port, uint8_t pin, enum Mode mode);
void gpio_setMode(void *port, uint8_t pin, enum Mode mode);
/**
* Map alternate function to GPIO pin. The pin has to be configured in alternate
@ -65,7 +64,7 @@ void gpio_setMode(GPIO_TypeDef *port, uint8_t pin, enum Mode mode);
* @param afNum: alternate function number, retrieved from mapping table in
* microcontroller's datasheet.
*/
void gpio_setAlternateFunction(GPIO_TypeDef *port, uint8_t pin, uint8_t afNum);
void gpio_setAlternateFunction(void *port, uint8_t pin, uint8_t afNum);
/**
* Configure GPIO pin maximum output speed.
@ -73,7 +72,7 @@ void gpio_setAlternateFunction(GPIO_TypeDef *port, uint8_t pin, uint8_t afNum);
* @param pin: GPIO pin number, between 0 and 15.
* @param spd: GPIO output speed to be set.
*/
void gpio_setOutputSpeed(GPIO_TypeDef *port, uint8_t pin, enum Speed spd);
void gpio_setOutputSpeed(void *port, uint8_t pin, enum Speed spd);
/**
* Set GPIO pin to high logic level.
@ -81,7 +80,7 @@ void gpio_setOutputSpeed(GPIO_TypeDef *port, uint8_t pin, enum Speed spd);
* @param port: GPIO port, it has to be equal to GPIOA_BASE, GPIOB_BASE, ...
* @param pin: GPIO pin number, between 0 and 15.
*/
void gpio_setPin(GPIO_TypeDef *port, uint8_t pin);
void gpio_setPin(void *port, uint8_t pin);
/**
* Set GPIO pin to low logic level.
@ -89,7 +88,7 @@ void gpio_setPin(GPIO_TypeDef *port, uint8_t pin);
* @param port: GPIO port, it has to be equal to GPIOA_BASE, GPIOB_BASE, ...
* @param pin: GPIO pin number, between 0 and 15.
*/
void gpio_clearPin(GPIO_TypeDef *port, uint8_t pin);
void gpio_clearPin(void *port, uint8_t pin);
/**
* Toggle logic level of a GPIO pin, with respect to its state before calling
@ -97,7 +96,7 @@ void gpio_clearPin(GPIO_TypeDef *port, uint8_t pin);
* @param port: GPIO port, it has to be equal to GPIOA_BASE, GPIOB_BASE, ...
* @param pin: GPIO pin number, between 0 and 15.
*/
void gpio_togglePin(GPIO_TypeDef *port, uint8_t pin);
void gpio_togglePin(void *port, uint8_t pin);
/**
* Read GPIO pin's logic level.
@ -105,6 +104,6 @@ void gpio_togglePin(GPIO_TypeDef *port, uint8_t pin);
* @param pin: GPIO pin number, between 0 and 15.
* @return 1 if pin is at high logic level, 0 if pin is at low logic level.
*/
uint8_t gpio_readPin(const GPIO_TypeDef *port, uint8_t pin);
uint8_t gpio_readPin(const void *port, uint8_t pin);
#endif /* GPIO_H */

View File

@ -24,6 +24,7 @@
#include "display.h"
#include "delays.h"
#include "hwconfig.h"
#include "stm32f4xx.h"
/* Defines for GPIO control, really ugly but useful. */
#define D0 GPIOD,14

View File

@ -15,119 +15,123 @@
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include "stm32f4xx.h"
#include "gpio.h"
void gpio_setMode(GPIO_TypeDef *port, uint8_t pin, enum Mode mode)
void gpio_setMode(void *port, uint8_t pin, enum Mode mode)
{
port->MODER &= ~(3 << (pin*2));
port->OTYPER &= ~(1 << pin);
port->PUPDR &= ~(3 << (pin*2));
GPIO_TypeDef *p = (GPIO_TypeDef *)(port);
p->MODER &= ~(3 << (pin*2));
p->OTYPER &= ~(1 << pin);
p->PUPDR &= ~(3 << (pin*2));
switch(mode)
{
case INPUT:
// (MODE=00 TYPE=0 PUP=00)
port->MODER |= 0x00 << (pin*2);
port->OTYPER |= 0x00 << pin;
port->PUPDR |= 0x00 << (pin*2);
p->MODER |= 0x00 << (pin*2);
p->OTYPER |= 0x00 << pin;
p->PUPDR |= 0x00 << (pin*2);
break;
case INPUT_PULL_UP:
// (MODE=00 TYPE=0 PUP=01)
port->MODER |= 0x00 << (pin*2);
port->OTYPER |= 0x00 << pin;
port->PUPDR |= 0x01 << (pin*2);
p->MODER |= 0x00 << (pin*2);
p->OTYPER |= 0x00 << pin;
p->PUPDR |= 0x01 << (pin*2);
break;
case INPUT_PULL_DOWN:
// (MODE=00 TYPE=0 PUP=10)
port->MODER |= 0x00 << (pin*2);
port->OTYPER |= 0x00 << pin;
port->PUPDR |= 0x02 << (pin*2);
p->MODER |= 0x00 << (pin*2);
p->OTYPER |= 0x00 << pin;
p->PUPDR |= 0x02 << (pin*2);
break;
case INPUT_ANALOG:
// (MODE=11 TYPE=0 PUP=00)
port->MODER |= 0x03 << (pin*2);
port->OTYPER |= 0x00 << pin;
port->PUPDR |= 0x00 << (pin*2);
p->MODER |= 0x03 << (pin*2);
p->OTYPER |= 0x00 << pin;
p->PUPDR |= 0x00 << (pin*2);
break;
case OUTPUT:
// (MODE=01 TYPE=0 PUP=00)
port->MODER |= 0x01 << (pin*2);
port->OTYPER |= 0x00 << pin;
port->PUPDR |= 0x00 << (pin*2);
p->MODER |= 0x01 << (pin*2);
p->OTYPER |= 0x00 << pin;
p->PUPDR |= 0x00 << (pin*2);
break;
case OPEN_DRAIN:
// (MODE=01 TYPE=1 PUP=00)
port->MODER |= 0x01 << (pin*2);
port->OTYPER |= 0x01 << pin;
port->PUPDR |= 0x00 << (pin*2);
p->MODER |= 0x01 << (pin*2);
p->OTYPER |= 0x01 << pin;
p->PUPDR |= 0x00 << (pin*2);
break;
case ALTERNATE:
// (MODE=10 TYPE=0 PUP=00)
port->MODER |= 0x02 << (pin*2);
port->OTYPER |= 0x00 << pin;
port->PUPDR |= 0x00 << (pin*2);
p->MODER |= 0x02 << (pin*2);
p->OTYPER |= 0x00 << pin;
p->PUPDR |= 0x00 << (pin*2);
break;
case ALTERNATE_OD:
// (MODE=10 TYPE=1 PUP=00)
port->MODER |= 0x02 << (pin*2);
port->OTYPER |= 0x01 << pin;
port->PUPDR |= 0x00 << (pin*2);
p->MODER |= 0x02 << (pin*2);
p->OTYPER |= 0x01 << pin;
p->PUPDR |= 0x00 << (pin*2);
break;
default:
// Default to INPUT mode
port->MODER |= 0x00 << (pin*2);
port->OTYPER |= 0x00 << pin;
port->PUPDR |= 0x00 << (pin*2);
p->MODER |= 0x00 << (pin*2);
p->OTYPER |= 0x00 << pin;
p->PUPDR |= 0x00 << (pin*2);
break;
}
}
void gpio_setAlternateFunction(GPIO_TypeDef *port, uint8_t pin, uint8_t afNum)
void gpio_setAlternateFunction(void *port, uint8_t pin, uint8_t afNum)
{
GPIO_TypeDef *p = (GPIO_TypeDef *)(port);
afNum &= 0x0F;
if(pin < 8)
{
port->AFR[0] &= ~(0x0F << (pin*4));
port->AFR[0] |= (afNum << (pin*4));
p->AFR[0] &= ~(0x0F << (pin*4));
p->AFR[0] |= (afNum << (pin*4));
}
else
{
pin -= 8;
port->AFR[1] &= ~(0x0F << (pin*4));
port->AFR[1] |= (afNum << (pin*4));
p->AFR[1] &= ~(0x0F << (pin*4));
p->AFR[1] |= (afNum << (pin*4));
}
}
void gpio_setOutputSpeed(GPIO_TypeDef *port, uint8_t pin, enum Speed spd)
void gpio_setOutputSpeed(void *port, uint8_t pin, enum Speed spd)
{
port->OSPEEDR &= ~(3 << (pin*2)); // Clear old value
port->OSPEEDR |= spd << (pin*2); // Set new value
((GPIO_TypeDef *)(port))->OSPEEDR &= ~(3 << (pin*2)); // Clear old value
((GPIO_TypeDef *)(port))->OSPEEDR |= spd << (pin*2); // Set new value
}
void gpio_setPin(GPIO_TypeDef *port, uint8_t pin)
void gpio_setPin(void *port, uint8_t pin)
{
port->BSRRL = (1 << pin);
((GPIO_TypeDef *)(port))->BSRRL = (1 << pin);
}
void gpio_clearPin(GPIO_TypeDef *port, uint8_t pin)
void gpio_clearPin(void *port, uint8_t pin)
{
port->BSRRH = (1 << pin);
((GPIO_TypeDef *)(port))->BSRRH = (1 << pin);
}
void gpio_togglePin(GPIO_TypeDef *port, uint8_t pin)
void gpio_togglePin(void *port, uint8_t pin)
{
port->ODR ^= (1 << pin);
((GPIO_TypeDef *)(port))->ODR ^= (1 << pin);
}
uint8_t gpio_readPin(const GPIO_TypeDef *port, uint8_t pin)
uint8_t gpio_readPin(const void *port, uint8_t pin)
{
return ((port->IDR & (1 << pin)) != 0) ? 1 : 0;
GPIO_TypeDef *p = (GPIO_TypeDef *)(port);
return ((p->IDR & (1 << pin)) != 0) ? 1 : 0;
}