diff --git a/platform/drivers/ADC/ADC1_MDx.c b/platform/drivers/ADC/ADC1_MDx.c
index c3456a2a..2b31ebe8 100644
--- a/platform/drivers/ADC/ADC1_MDx.c
+++ b/platform/drivers/ADC/ADC1_MDx.c
@@ -34,16 +34,16 @@ void adc1_init()
/*
* Configure GPIOs to analog input mode:
*/
- gpio_setMode(AIN_VBAT, INPUT_ANALOG);
- gpio_setMode(AIN_VOLUME, INPUT_ANALOG);
+ gpio_setMode(AIN_VBAT, ANALOG);
+ gpio_setMode(AIN_VOLUME, ANALOG);
#if defined(PLATFORM_MD3x0) || defined(PLATFORM_MD9600)
- gpio_setMode(AIN_MIC, INPUT_ANALOG);
- gpio_setMode(AIN_RSSI, INPUT_ANALOG);
+ gpio_setMode(AIN_MIC, ANALOG);
+ gpio_setMode(AIN_RSSI, ANALOG);
#if defined(PLATFORM_MD9600)
- gpio_setMode(AIN_SW2, INPUT_ANALOG);
- gpio_setMode(AIN_SW1, INPUT_ANALOG);
- gpio_setMode(AIN_RSSI2, INPUT_ANALOG);
- gpio_setMode(AIN_HTEMP, INPUT_ANALOG);
+ gpio_setMode(AIN_SW2, ANALOG);
+ gpio_setMode(AIN_SW1, ANALOG);
+ gpio_setMode(AIN_RSSI2, ANALOG);
+ gpio_setMode(AIN_HTEMP, ANALOG);
#endif
#endif
diff --git a/platform/drivers/ADC/ADC1_Mod17.c b/platform/drivers/ADC/ADC1_Mod17.c
index d1e6d7d8..0e8ffdd1 100644
--- a/platform/drivers/ADC/ADC1_Mod17.c
+++ b/platform/drivers/ADC/ADC1_Mod17.c
@@ -34,7 +34,7 @@ void adc1_init()
/*
* Configure GPIOs to analog input mode:
*/
- gpio_setMode(AIN_HWVER, INPUT_ANALOG);
+ gpio_setMode(AIN_HWVER, ANALOG);
/*
* ADC clock is APB2 frequency divided by 8, giving 10.5MHz.
diff --git a/platform/drivers/GPS/GPS_MDx.cpp b/platform/drivers/GPS/GPS_MDx.cpp
index 89dc077f..059012b5 100644
--- a/platform/drivers/GPS/GPS_MDx.cpp
+++ b/platform/drivers/GPS/GPS_MDx.cpp
@@ -109,8 +109,7 @@ void __attribute__((naked)) USART1_IRQHandler()
void gps_init(const uint16_t baud)
{
gpio_setMode(GPS_EN, OUTPUT);
- gpio_setMode(GPS_DATA, ALTERNATE);
- gpio_setAlternateFunction(GPS_DATA, 7);
+ gpio_setMode(GPS_DATA, ALTERNATE | ALTERNATE_FUNC(7));
#ifdef PLATFORM_MD3x0
const unsigned int quot = 2*42000000/baud; /* APB1 clock is 42MHz */
diff --git a/platform/drivers/NVM/spiFlash_MD3x.c b/platform/drivers/NVM/spiFlash_MD3x.c
index 13a23b6a..e07c9753 100644
--- a/platform/drivers/NVM/spiFlash_MD3x.c
+++ b/platform/drivers/NVM/spiFlash_MD3x.c
@@ -35,12 +35,9 @@ uint8_t spiFlash_SendRecv(uint8_t val)
void spiFlash_init()
{
- gpio_setMode(FLASH_CLK, ALTERNATE);
- gpio_setMode(FLASH_SDO, ALTERNATE);
- gpio_setMode(FLASH_SDI, ALTERNATE);
- gpio_setAlternateFunction(FLASH_CLK, 5); /* SPI1 is on AF5 */
- gpio_setAlternateFunction(FLASH_SDO, 5);
- gpio_setAlternateFunction(FLASH_SDI, 5);
+ gpio_setMode(FLASH_CLK, ALTERNATE | ALTERNATE_FUNC(5));
+ gpio_setMode(FLASH_SDO, ALTERNATE | ALTERNATE_FUNC(5));
+ gpio_setMode(FLASH_SDI, ALTERNATE | ALTERNATE_FUNC(5));
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
__DSB();
diff --git a/platform/drivers/USB/usb_MDx.cpp b/platform/drivers/USB/usb_MDx.cpp
index ef0aad43..e125fc59 100644
--- a/platform/drivers/USB/usb_MDx.cpp
+++ b/platform/drivers/USB/usb_MDx.cpp
@@ -35,12 +35,10 @@ void OTG_FS_IRQHandler(void)
void usb_init()
{
- gpio_setMode(GPIOA, 11, ALTERNATE);
- gpio_setAlternateFunction(GPIOA, 11, 10);
- gpio_setOutputSpeed(GPIOA, 11, HIGH); // 100MHz output speed
+ gpio_setMode(GPIOA, 11, ALTERNATE | ALTERNATE_FUNC(10));
+ gpio_setMode(GPIOA, 12, ALTERNATE | ALTERNATE_FUNC(10));
- gpio_setMode(GPIOA, 12, ALTERNATE);
- gpio_setAlternateFunction(GPIOA, 12, 10);
+ gpio_setOutputSpeed(GPIOA, 11, HIGH); // 100MHz output speed
gpio_setOutputSpeed(GPIOA, 12, HIGH); // 100MHz output speed
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
diff --git a/platform/drivers/audio/audio_MDx.c b/platform/drivers/audio/audio_MDx.c
index 014f1e80..1d554587 100644
--- a/platform/drivers/audio/audio_MDx.c
+++ b/platform/drivers/audio/audio_MDx.c
@@ -80,10 +80,10 @@ const struct audioDevice inputDevices[] =
void audio_init()
{
- gpio_setMode(AIN_MIC, INPUT_ANALOG);
+ gpio_setMode(AIN_MIC, ANALOG);
gpio_setMode(SPK_MUTE, OUTPUT);
#ifndef PLATFORM_MD9600
- gpio_setMode(AIN_RTX, INPUT_ANALOG);
+ gpio_setMode(AIN_RTX, ANALOG);
gpio_setMode(AUDIO_AMP_EN, OUTPUT);
#ifndef MDx_ENABLE_SWD
gpio_setMode(MIC_PWR, OUTPUT);
@@ -138,7 +138,7 @@ void audio_connect(const enum AudioSource source, const enum AudioSink sink)
case PATH(SOURCE_MCU, SINK_SPK):
case PATH(SOURCE_MCU, SINK_RTX):
- gpio_setMode(BEEP_OUT, ALTERNATE);
+ gpio_setMode(BEEP_OUT, ALTERNATE | ALTERNATE_FUNC(2));
break;
default:
diff --git a/platform/drivers/audio/audio_Mod17.c b/platform/drivers/audio/audio_Mod17.c
index ebecb273..8e87d609 100644
--- a/platform/drivers/audio/audio_Mod17.c
+++ b/platform/drivers/audio/audio_Mod17.c
@@ -58,10 +58,10 @@ void audio_init()
{
gpio_setMode(SPK_MUTE, OUTPUT);
gpio_setMode(MIC_MUTE, OUTPUT);
- gpio_setMode(AUDIO_MIC, INPUT_ANALOG);
- gpio_setMode(AUDIO_SPK, INPUT_ANALOG);
- gpio_setMode(BASEBAND_RX, INPUT_ANALOG);
- gpio_setMode(BASEBAND_TX, INPUT_ANALOG);
+ gpio_setMode(AUDIO_MIC, ANALOG);
+ gpio_setMode(AUDIO_SPK, ANALOG);
+ gpio_setMode(BASEBAND_RX, ANALOG);
+ gpio_setMode(BASEBAND_TX, ANALOG);
gpio_setPin(SPK_MUTE); // Off = logic high
gpio_clearPin(MIC_MUTE); // Off = logic low
diff --git a/platform/drivers/backlight/backlight_MDx.c b/platform/drivers/backlight/backlight_MDx.c
index a8d1c3b9..37cd4afd 100644
--- a/platform/drivers/backlight/backlight_MDx.c
+++ b/platform/drivers/backlight/backlight_MDx.c
@@ -54,8 +54,7 @@ void _Z29TIM1_TRG_COM_TIM11_IRQHandlerv()
void backlight_init()
{
#ifndef PLATFORM_MDUV3x0 /* MD-3x0 and MD-9600 */
- gpio_setMode(LCD_BKLIGHT, ALTERNATE);
- gpio_setAlternateFunction(LCD_BKLIGHT, 3);
+ gpio_setMode(LCD_BKLIGHT, ALTERNATE | ALTERNATE_FUNC(3));
/*
* Configure TIM8 for backlight PWM: Fpwm = 1kHz with 8 bit of resolution.
diff --git a/platform/drivers/baseband/radio_MD3x0.cpp b/platform/drivers/baseband/radio_MD3x0.cpp
index 7d454060..eaf343b2 100644
--- a/platform/drivers/baseband/radio_MD3x0.cpp
+++ b/platform/drivers/baseband/radio_MD3x0.cpp
@@ -115,8 +115,8 @@ void radio_init(const rtxStatus_t *rtxState)
/*
* Configure and enable DAC
*/
- gpio_setMode(APC_TV, INPUT_ANALOG);
- gpio_setMode(MOD2_BIAS, INPUT_ANALOG);
+ gpio_setMode(APC_TV, ANALOG);
+ gpio_setMode(MOD2_BIAS, ANALOG);
RCC->APB1ENR |= RCC_APB1ENR_DACEN;
DAC->CR = DAC_CR_EN2 | DAC_CR_EN1;
DAC->DHR12R2 = 0;
diff --git a/platform/drivers/baseband/radio_UV3x0.cpp b/platform/drivers/baseband/radio_UV3x0.cpp
index d2330258..3de4aaa3 100644
--- a/platform/drivers/baseband/radio_UV3x0.cpp
+++ b/platform/drivers/baseband/radio_UV3x0.cpp
@@ -73,7 +73,7 @@ void radio_init(const rtxStatus_t *rtxState)
/*
* Configure and enable DAC
*/
- gpio_setMode(APC_REF, INPUT_ANALOG);
+ gpio_setMode(APC_REF, ANALOG);
RCC->APB1ENR |= RCC_APB1ENR_DACEN;
DAC->CR = DAC_CR_EN1;
diff --git a/platform/drivers/display/HX8353_MD3x.cpp b/platform/drivers/display/HX8353_MD3x.cpp
index 949858a7..47c3f1ff 100644
--- a/platform/drivers/display/HX8353_MD3x.cpp
+++ b/platform/drivers/display/HX8353_MD3x.cpp
@@ -180,29 +180,17 @@ void display_init()
| 7; /* ADDSET */
/* Configure alternate function for data and control lines. */
- gpio_setMode(LCD_D0, ALTERNATE);
- gpio_setMode(LCD_D1, ALTERNATE);
- gpio_setMode(LCD_D2, ALTERNATE);
- gpio_setMode(LCD_D3, ALTERNATE);
- gpio_setMode(LCD_D4, ALTERNATE);
- gpio_setMode(LCD_D5, ALTERNATE);
- gpio_setMode(LCD_D6, ALTERNATE);
- gpio_setMode(LCD_D7, ALTERNATE);
- gpio_setMode(LCD_RS, ALTERNATE);
- gpio_setMode(LCD_WR, ALTERNATE);
- gpio_setMode(LCD_RD, ALTERNATE);
-
- gpio_setAlternateFunction(LCD_D0, 12);
- gpio_setAlternateFunction(LCD_D1, 12);
- gpio_setAlternateFunction(LCD_D2, 12);
- gpio_setAlternateFunction(LCD_D3, 12);
- gpio_setAlternateFunction(LCD_D4, 12);
- gpio_setAlternateFunction(LCD_D5, 12);
- gpio_setAlternateFunction(LCD_D6, 12);
- gpio_setAlternateFunction(LCD_D7, 12);
- gpio_setAlternateFunction(LCD_RS, 12);
- gpio_setAlternateFunction(LCD_WR, 12);
- gpio_setAlternateFunction(LCD_RD, 12);
+ gpio_setMode(LCD_D0, ALTERNATE | ALTERNATE_FUNC(12));
+ gpio_setMode(LCD_D1, ALTERNATE | ALTERNATE_FUNC(12));
+ gpio_setMode(LCD_D2, ALTERNATE | ALTERNATE_FUNC(12));
+ gpio_setMode(LCD_D3, ALTERNATE | ALTERNATE_FUNC(12));
+ gpio_setMode(LCD_D4, ALTERNATE | ALTERNATE_FUNC(12));
+ gpio_setMode(LCD_D5, ALTERNATE | ALTERNATE_FUNC(12));
+ gpio_setMode(LCD_D6, ALTERNATE | ALTERNATE_FUNC(12));
+ gpio_setMode(LCD_D7, ALTERNATE | ALTERNATE_FUNC(12));
+ gpio_setMode(LCD_RS, ALTERNATE | ALTERNATE_FUNC(12));
+ gpio_setMode(LCD_WR, ALTERNATE | ALTERNATE_FUNC(12));
+ gpio_setMode(LCD_RD, ALTERNATE | ALTERNATE_FUNC(12));
/* Reset and chip select lines as outputs */
gpio_setMode(LCD_CS, OUTPUT);
@@ -439,14 +427,14 @@ void display_renderRows(uint8_t startRow, uint8_t endRow, void *fb)
* Put screen data lines back to alternate function mode, since they are in
* common with keyboard buttons and the keyboard driver sets them as inputs.
*/
- gpio_setMode(LCD_D0, ALTERNATE);
- gpio_setMode(LCD_D1, ALTERNATE);
- gpio_setMode(LCD_D2, ALTERNATE);
- gpio_setMode(LCD_D3, ALTERNATE);
- gpio_setMode(LCD_D4, ALTERNATE);
- gpio_setMode(LCD_D5, ALTERNATE);
- gpio_setMode(LCD_D6, ALTERNATE);
- gpio_setMode(LCD_D7, ALTERNATE);
+ gpio_setMode(LCD_D0, ALTERNATE | ALTERNATE_FUNC(12));
+ gpio_setMode(LCD_D1, ALTERNATE | ALTERNATE_FUNC(12));
+ gpio_setMode(LCD_D2, ALTERNATE | ALTERNATE_FUNC(12));
+ gpio_setMode(LCD_D3, ALTERNATE | ALTERNATE_FUNC(12));
+ gpio_setMode(LCD_D4, ALTERNATE | ALTERNATE_FUNC(12));
+ gpio_setMode(LCD_D5, ALTERNATE | ALTERNATE_FUNC(12));
+ gpio_setMode(LCD_D6, ALTERNATE | ALTERNATE_FUNC(12));
+ gpio_setMode(LCD_D7, ALTERNATE | ALTERNATE_FUNC(12));
gpio_clearPin(LCD_CS);
diff --git a/platform/drivers/display/SH110x_Mod17.c b/platform/drivers/display/SH110x_Mod17.c
index cbe53730..05804b16 100644
--- a/platform/drivers/display/SH110x_Mod17.c
+++ b/platform/drivers/display/SH110x_Mod17.c
@@ -35,12 +35,9 @@ void display_init()
/*
* Initialise SPI2 for external flash and LCD
*/
- gpio_setMode(SPI2_CLK, ALTERNATE);
- gpio_setMode(SPI2_SDO, ALTERNATE);
- gpio_setMode(SPI2_SDI, ALTERNATE);
- gpio_setAlternateFunction(SPI2_CLK, 5); /* SPI2 is on AF5 */
- gpio_setAlternateFunction(SPI2_SDO, 5);
- gpio_setAlternateFunction(SPI2_SDI, 5);
+ gpio_setMode(SPI2_CLK, ALTERNATE | ALTERNATE_FUNC(5));
+ gpio_setMode(SPI2_SDO, ALTERNATE | ALTERNATE_FUNC(5));
+ gpio_setMode(SPI2_SDI, ALTERNATE | ALTERNATE_FUNC(5));
spi2_init();
diff --git a/platform/drivers/display/SSD1306_Mod17.c b/platform/drivers/display/SSD1306_Mod17.c
index ee115485..d23ef395 100644
--- a/platform/drivers/display/SSD1306_Mod17.c
+++ b/platform/drivers/display/SSD1306_Mod17.c
@@ -60,12 +60,9 @@ void display_init()
/*
* Initialise SPI2 for external flash and LCD
*/
- gpio_setMode(SPI2_CLK, ALTERNATE);
- gpio_setMode(SPI2_SDO, ALTERNATE);
- gpio_setMode(SPI2_SDI, ALTERNATE);
- gpio_setAlternateFunction(SPI2_CLK, 5); /* SPI2 is on AF5 */
- gpio_setAlternateFunction(SPI2_SDO, 5);
- gpio_setAlternateFunction(SPI2_SDI, 5);
+ gpio_setMode(SPI2_CLK, ALTERNATE | ALTERNATE_FUNC(5));
+ gpio_setMode(SPI2_SDO, ALTERNATE | ALTERNATE_FUNC(5));
+ gpio_setMode(SPI2_SDI, ALTERNATE | ALTERNATE_FUNC(5));
spi2_init();
diff --git a/platform/drivers/tones/toneGenerator_MDx.cpp b/platform/drivers/tones/toneGenerator_MDx.cpp
index 487eaf6a..347ee94f 100644
--- a/platform/drivers/tones/toneGenerator_MDx.cpp
+++ b/platform/drivers/tones/toneGenerator_MDx.cpp
@@ -101,9 +101,7 @@ void toneGen_init()
* NOTE: change of "beep" output gpio to alternate/input mode is handled by
* the audio driver.
*/
- gpio_setMode(CTCSS_OUT, ALTERNATE);
- gpio_setAlternateFunction(CTCSS_OUT, 2);
- gpio_setAlternateFunction(BEEP_OUT, 2);
+ gpio_setMode(CTCSS_OUT, ALTERNATE | ALTERNATE_FUNC(2));
/*
* TIM3 configuration:
diff --git a/platform/mcu/STM32F4xx/drivers/USART3.cpp b/platform/mcu/STM32F4xx/drivers/USART3.cpp
index b7ffa1f9..a5c2e796 100644
--- a/platform/mcu/STM32F4xx/drivers/USART3.cpp
+++ b/platform/mcu/STM32F4xx/drivers/USART3.cpp
@@ -95,10 +95,8 @@ void __attribute__((noinline)) usart3irqImpl()
void usart3_init(unsigned int baudrate)
{
- gpio_setMode(U3RXD, ALTERNATE);
- gpio_setMode(U3TXD, ALTERNATE);
- gpio_setAlternateFunction(U3RXD, 7);
- gpio_setAlternateFunction(U3TXD, 7);
+ gpio_setMode(U3RXD, ALTERNATE | ALTERNATE_FUNC(7));
+ gpio_setMode(U3TXD, ALTERNATE | ALTERNATE_FUNC(7));
RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
__DSB();
diff --git a/platform/mcu/STM32F4xx/drivers/gpio-native.h b/platform/mcu/STM32F4xx/drivers/gpio-native.h
new file mode 100644
index 00000000..73909226
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/gpio-native.h
@@ -0,0 +1,114 @@
+/***************************************************************************
+ * Copyright (C) 2024 by Silvano Seva IU2KWO *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, see *
+ ***************************************************************************/
+
+#ifndef GPIO_NATIVE_H
+#define GPIO_NATIVE_H
+
+#include
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This file provides the interface for STM32 gpio.
+ */
+
+/**
+ * Maximum GPIO switching speed.
+ * For more details see microcontroller's reference manual and datasheet.
+ */
+enum Speed
+{
+ LOW = 0x0, ///< 2MHz
+ MEDIUM = 0x1, ///< 25MHz
+ FAST = 0x2, ///< 50MHz
+ HIGH = 0x3 ///< 100MHz
+};
+
+/**
+ * STM32 gpio devices
+ */
+extern const struct gpioDev GpioA;
+extern const struct gpioDev GpioB;
+extern const struct gpioDev GpioC;
+extern const struct gpioDev GpioD;
+extern const struct gpioDev GpioE;
+
+/**
+ * Configure gpio pin functional mode.
+ *
+ * @param port: gpio port.
+ * @param pin: gpio pin number, between 0 and 15.
+ * @param mode: bit 7:0 set gpio functional mode, bit 15:8 manage gpio alternate
+ * function mapping.
+ */
+void gpio_setMode(const void *port, const uint8_t pin, const uint16_t mode);
+
+/**
+ * Configure gpio pin maximum output speed.
+ *
+ * @param port: gpio port.
+ * @param pin: gpio pin number, between 0 and 15.
+ * @param spd: gpio output speed to be set.
+ */
+void gpio_setOutputSpeed(const void *port, const uint8_t pin, const enum Speed spd);
+
+/**
+ * Set gpio pin to high logic level.
+ * NOTE: this operation is performed atomically.
+ *
+ * @param port: gpio port.
+ * @param pin: gpio pin number, between 0 and 15.
+ */
+static inline void gpio_setPin(const void *port, const uint8_t pin)
+{
+ ((GPIO_TypeDef *)(port))->BSRR = (1 << pin);
+}
+
+/**
+ * Set gpio pin to low logic level.
+ * NOTE: this operation is performed atomically.
+ *
+ * @param port: gpio port.
+ * @param pin: gpio pin number, between 0 and 15.
+ */
+static inline void gpio_clearPin(const void *port, const uint8_t pin)
+{
+ ((GPIO_TypeDef *)(port))->BSRR = (1 << (pin + 16));
+}
+
+/**
+ * Read gpio pin's logic level.
+ *
+ * @param port: gpio port.
+ * @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.
+ */
+static inline uint8_t gpio_readPin(const void *port, const uint8_t pin)
+{
+ GPIO_TypeDef *p = (GPIO_TypeDef *)(port);
+ return ((p->IDR & (1 << pin)) != 0) ? 1 : 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GPIO_NATIVE_H */
diff --git a/platform/mcu/STM32F4xx/drivers/gpio.c b/platform/mcu/STM32F4xx/drivers/gpio.c
index c45d655a..d6763c25 100644
--- a/platform/mcu/STM32F4xx/drivers/gpio.c
+++ b/platform/mcu/STM32F4xx/drivers/gpio.c
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2020 - 2023 by Silvano Seva IU2KWO *
+ * Copyright (C) 2020 - 2024 by Silvano Seva IU2KWO *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
@@ -15,17 +15,35 @@
* along with this program; if not, see *
***************************************************************************/
+#include
#include "stm32f4xx.h"
-#include
+#include "gpio-native.h"
-void gpio_setMode(void *port, uint8_t pin, enum Mode mode)
+static inline void setGpioAf(GPIO_TypeDef *port, uint8_t pin, const uint8_t af)
+{
+ if(pin < 8)
+ {
+ port->AFR[0] &= ~(0x0F << (pin*4));
+ port->AFR[0] |= (af << (pin*4));
+ }
+ else
+ {
+ pin -= 8;
+ port->AFR[1] &= ~(0x0F << (pin*4));
+ port->AFR[1] |= (af << (pin*4));
+ }
+}
+
+void gpio_setMode(const void *port, const uint8_t pin, const uint16_t mode)
{
GPIO_TypeDef *p = (GPIO_TypeDef *)(port);
+ uint8_t af = (mode >> 8) & 0x0F;
+
p->MODER &= ~(3 << (pin*2));
p->OTYPER &= ~(1 << pin);
p->PUPDR &= ~(3 << (pin*2));
- switch(mode)
+ switch(mode & 0xFF)
{
case INPUT:
// (MODE=00 TYPE=0 PUP=00)
@@ -48,7 +66,7 @@ void gpio_setMode(void *port, uint8_t pin, enum Mode mode)
p->PUPDR |= 0x02 << (pin*2);
break;
- case INPUT_ANALOG:
+ case ANALOG:
// (MODE=11 TYPE=0 PUP=00)
p->MODER |= 0x03 << (pin*2);
p->OTYPER |= 0x00 << pin;
@@ -69,11 +87,19 @@ void gpio_setMode(void *port, uint8_t pin, enum Mode mode)
p->PUPDR |= 0x00 << (pin*2);
break;
+ case OPEN_DRAIN_PU:
+ // (MODE=01 TYPE=1 PUP=01)
+ p->MODER |= 0x01 << (pin*2);
+ p->OTYPER |= 0x01 << pin;
+ p->PUPDR |= 0x00 << (pin*2);
+ break;
+
case ALTERNATE:
// (MODE=10 TYPE=0 PUP=00)
p->MODER |= 0x02 << (pin*2);
p->OTYPER |= 0x00 << pin;
- p->PUPDR |= 0x00 << (pin*2);
+ p->PUPDR |= 0x01 << (pin*2);
+ setGpioAf(p, pin, af);
break;
case ALTERNATE_OD:
@@ -81,6 +107,15 @@ void gpio_setMode(void *port, uint8_t pin, enum Mode mode)
p->MODER |= 0x02 << (pin*2);
p->OTYPER |= 0x01 << pin;
p->PUPDR |= 0x00 << (pin*2);
+ setGpioAf(p, pin, af);
+ break;
+
+ case ALTERNATE_OD_PU:
+ // (MODE=10 TYPE=1 PUP=01)
+ p->MODER |= 0x02 << (pin*2);
+ p->OTYPER |= 0x01 << pin;
+ p->PUPDR |= 0x01 << (pin*2);
+ setGpioAf(p, pin, af);
break;
default:
@@ -92,46 +127,48 @@ void gpio_setMode(void *port, uint8_t pin, enum Mode mode)
}
}
-void gpio_setAlternateFunction(void *port, uint8_t pin, uint8_t afNum)
-{
- GPIO_TypeDef *p = (GPIO_TypeDef *)(port);
- afNum &= 0x0F;
- if(pin < 8)
- {
- p->AFR[0] &= ~(0x0F << (pin*4));
- p->AFR[0] |= (afNum << (pin*4));
- }
- else
- {
- pin -= 8;
- p->AFR[1] &= ~(0x0F << (pin*4));
- p->AFR[1] |= (afNum << (pin*4));
- }
-}
-
-void gpio_setOutputSpeed(void *port, uint8_t pin, enum Speed spd)
+void gpio_setOutputSpeed(const void *port, const uint8_t pin, const enum Speed spd)
{
((GPIO_TypeDef *)(port))->OSPEEDR &= ~(3 << (pin*2)); // Clear old value
((GPIO_TypeDef *)(port))->OSPEEDR |= spd << (pin*2); // Set new value
}
-void gpio_setPin(void *port, uint8_t pin)
+static int gpioApi_mode(const struct gpioDev *dev, const uint8_t pin,
+ const uint16_t mode)
{
- ((GPIO_TypeDef *)(port))->BSRR = (1 << pin);
+ if(pin > 15)
+ return -EINVAL;
+
+ gpio_setMode((void *) dev->priv, pin, mode);
+ return 0;
}
-void gpio_clearPin(void *port, uint8_t pin)
+static void gpioApi_set(const struct gpioDev *dev, const uint8_t pin)
{
- ((GPIO_TypeDef *)(port))->BSRR = (1 << (pin + 16));
+ gpio_setPin((void *) dev->priv, pin);
}
-void gpio_togglePin(void *port, uint8_t pin)
+static void gpioApi_clear(const struct gpioDev *dev, const uint8_t pin)
{
- ((GPIO_TypeDef *)(port))->ODR ^= (1 << pin);
+ gpio_clearPin((void *) dev->priv, pin);
}
-uint8_t gpio_readPin(const void *port, uint8_t pin)
+static bool gpioApi_read(const struct gpioDev *dev, const uint8_t pin)
{
- GPIO_TypeDef *p = (GPIO_TypeDef *)(port);
- return ((p->IDR & (1 << pin)) != 0) ? 1 : 0;
+ uint8_t val = gpio_readPin(dev->priv, pin);
+ return (val != 0) ? true : false;
}
+
+static const struct gpioApi gpioApi =
+{
+ .mode = gpioApi_mode,
+ .set = gpioApi_set,
+ .clear = gpioApi_clear,
+ .read = gpioApi_read
+};
+
+const struct gpioDev GpioA = { .api = &gpioApi, .priv = GPIOA };
+const struct gpioDev GpioB = { .api = &gpioApi, .priv = GPIOB };
+const struct gpioDev GpioC = { .api = &gpioApi, .priv = GPIOC };
+const struct gpioDev GpioD = { .api = &gpioApi, .priv = GPIOD };
+const struct gpioDev GpioE = { .api = &gpioApi, .priv = GPIOE };
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usb_bsp.c b/platform/mcu/STM32F4xx/drivers/usb/usb_bsp.c
index 3fb56073..40076176 100644
--- a/platform/mcu/STM32F4xx/drivers/usb/usb_bsp.c
+++ b/platform/mcu/STM32F4xx/drivers/usb/usb_bsp.c
@@ -47,12 +47,10 @@ void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev)
{
(void) pdev;
- gpio_setMode(GPIOA, 11, ALTERNATE);
- gpio_setAlternateFunction(GPIOA, 11, 10);
- gpio_setOutputSpeed(GPIOA, 11, HIGH); // 100MHz output speed
+ gpio_setMode(GPIOA, 11, ALTERNATE | ALTERNATE_FUNC(10));
+ gpio_setMode(GPIOA, 12, ALTERNATE | ALTERNATE_FUNC(10));
- gpio_setMode(GPIOA, 12, ALTERNATE);
- gpio_setAlternateFunction(GPIOA, 12, 10);
+ gpio_setOutputSpeed(GPIOA, 11, HIGH); // 100MHz output speed
gpio_setOutputSpeed(GPIOA, 12, HIGH); // 100MHz output speed
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
diff --git a/platform/targets/MD-9600/platform.c b/platform/targets/MD-9600/platform.c
index 1666d112..a6e6dc1a 100644
--- a/platform/targets/MD-9600/platform.c
+++ b/platform/targets/MD-9600/platform.c
@@ -63,12 +63,9 @@ void platform_init()
/*
* Initialise SPI2 for external flash and LCD
*/
- gpio_setMode(SPI2_CLK, ALTERNATE);
- gpio_setMode(SPI2_SDO, ALTERNATE);
- gpio_setMode(SPI2_SDI, ALTERNATE);
- gpio_setAlternateFunction(SPI2_CLK, 5); /* SPI2 is on AF5 */
- gpio_setAlternateFunction(SPI2_SDO, 5);
- gpio_setAlternateFunction(SPI2_SDI, 5);
+ gpio_setMode(SPI2_CLK, ALTERNATE | ALTERNATE_FUNC(5));
+ gpio_setMode(SPI2_SDO, ALTERNATE | ALTERNATE_FUNC(5));
+ gpio_setMode(SPI2_SDI, ALTERNATE | ALTERNATE_FUNC(5));
spi2_init();
diff --git a/platform/targets/Module17/platform.c b/platform/targets/Module17/platform.c
index 4000a33c..c4ea1eda 100644
--- a/platform/targets/Module17/platform.c
+++ b/platform/targets/Module17/platform.c
@@ -59,7 +59,7 @@ void platform_init()
gpio_clearPin(PTT_OUT);
/* Set analog output for baseband signal to an idle level of 1.1V */
- gpio_setMode(BASEBAND_TX, INPUT_ANALOG);
+ gpio_setMode(BASEBAND_TX, ANALOG);
RCC->APB1ENR |= RCC_APB1ENR_DACEN;
DAC->CR |= DAC_CR_EN1;
DAC->DHR12R1 = 1365;