From 8842b98a5243b79f9527439e13ad142e5c45c3fa Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Sat, 25 May 2024 16:20:16 +0200 Subject: [PATCH] STM32F4xx: updated gpio driver --- platform/drivers/ADC/ADC1_MDx.c | 16 +-- platform/drivers/ADC/ADC1_Mod17.c | 2 +- platform/drivers/GPS/GPS_MDx.cpp | 3 +- platform/drivers/NVM/spiFlash_MD3x.c | 9 +- platform/drivers/USB/usb_MDx.cpp | 8 +- platform/drivers/audio/audio_MDx.c | 6 +- platform/drivers/audio/audio_Mod17.c | 8 +- platform/drivers/backlight/backlight_MDx.c | 3 +- platform/drivers/baseband/radio_MD3x0.cpp | 4 +- platform/drivers/baseband/radio_UV3x0.cpp | 2 +- platform/drivers/display/HX8353_MD3x.cpp | 50 ++++---- platform/drivers/display/SH110x_Mod17.c | 9 +- platform/drivers/display/SSD1306_Mod17.c | 9 +- platform/drivers/tones/toneGenerator_MDx.cpp | 4 +- platform/mcu/STM32F4xx/drivers/USART3.cpp | 6 +- platform/mcu/STM32F4xx/drivers/gpio-native.h | 114 +++++++++++++++++++ platform/mcu/STM32F4xx/drivers/gpio.c | 103 +++++++++++------ platform/mcu/STM32F4xx/drivers/usb/usb_bsp.c | 8 +- platform/targets/MD-9600/platform.c | 9 +- platform/targets/Module17/platform.c | 2 +- 20 files changed, 246 insertions(+), 129 deletions(-) create mode 100644 platform/mcu/STM32F4xx/drivers/gpio-native.h 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;