uartPort_t *serialUART5(uint32_t baudRate, portMode_t mode, portOptions_t options) { uartPort_t *s; static volatile uint8_t rx5Buffer[UART5_RX_BUFFER_SIZE]; static volatile uint8_t tx5Buffer[UART5_TX_BUFFER_SIZE]; NVIC_InitTypeDef NVIC_InitStructure; s = &uartPort5; s->port.vTable = uartVTable; s->port.baudRate = baudRate; s->port.rxBufferSize = UART5_RX_BUFFER_SIZE; s->port.txBufferSize = UART5_TX_BUFFER_SIZE; s->port.rxBuffer = rx5Buffer; s->port.txBuffer = tx5Buffer; s->USARTx = UART5; RCC_ClockCmd(RCC_APB1(UART5), ENABLE); serialUARTInit(IOGetByTag(IO_TAG(UART5_TX_PIN)), IOGetByTag(IO_TAG(UART5_RX_PIN)), mode, options, GPIO_AF_5, 5); NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART5); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART5); NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); return s; }
uartPort_t *serialUART3(uint32_t baudRate, portMode_t mode, portOptions_t options) { uartPort_t *s; static volatile uint8_t rx3Buffer[UART3_RX_BUFFER_SIZE]; static volatile uint8_t tx3Buffer[UART3_TX_BUFFER_SIZE]; s = &uartPort3; s->port.vTable = uartVTable; s->port.baudRate = baudRate; s->port.rxBufferSize = UART3_RX_BUFFER_SIZE; s->port.txBufferSize = UART3_TX_BUFFER_SIZE; s->port.rxBuffer = rx3Buffer; s->port.txBuffer = tx3Buffer; s->USARTx = USART3; #ifdef USE_UART3_RX_DMA s->rxDMAChannel = DMA1_Channel3; s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->RDR; #endif #ifdef USE_UART3_TX_DMA s->txDMAChannel = DMA1_Channel2; s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->TDR; #endif RCC_ClockCmd(RCC_APB1(USART3), ENABLE); #if defined(USE_UART3_TX_DMA) || defined(USE_UART3_RX_DMA) RCC_AHBClockCmd(RCC_AHB(DMA1), ENABLE); #endif serialUARTInit(IOGetByTag(IO_TAG(UART3_TX_PIN)), IOGetByTag(IO_TAG(UART3_RX_PIN)), mode, options, GPIO_AF_7, 3); #ifdef USE_UART3_TX_DMA // DMA TX Interrupt dmaSetHandler(DMA1_CH2_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART3_TXDMA, (uint32_t)&uartPort3); #endif #ifndef USE_UART3_RX_DMA NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART3_RXDMA); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART3_RXDMA); NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #endif return s; }
// USART2 - GPS or Spektrum or ?? (RX + TX by IRQ) uartPort_t *serialUART2(uint32_t baudRate, portMode_t mode, portOptions_t options) { uartPort_t *s; static volatile uint8_t rx2Buffer[UART2_RX_BUFFER_SIZE]; static volatile uint8_t tx2Buffer[UART2_TX_BUFFER_SIZE]; NVIC_InitTypeDef NVIC_InitStructure; s = &uartPort2; s->port.vTable = uartVTable; s->port.baudRate = baudRate; s->port.rxBufferSize = UART2_RX_BUFFER_SIZE; s->port.txBufferSize = UART2_TX_BUFFER_SIZE; s->port.rxBuffer = rx2Buffer; s->port.txBuffer = tx2Buffer; s->USARTx = USART2; s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR; s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR; RCC_ClockCmd(RCC_APB1(USART2), ENABLE); // UART2_TX PA2 // UART2_RX PA3 if (options & SERIAL_BIDIR) { IOInit(IOGetByTag(IO_TAG(PA2)), OWNER_SERIAL_TX, 2); IOConfigGPIO(IOGetByTag(IO_TAG(PA2)), IOCFG_AF_OD); } else { if (mode & MODE_TX) { IOInit(IOGetByTag(IO_TAG(PA2)), OWNER_SERIAL_TX, 2); IOConfigGPIO(IOGetByTag(IO_TAG(PA2)), IOCFG_AF_PP); } if (mode & MODE_RX) { IOInit(IOGetByTag(IO_TAG(PA3)), OWNER_SERIAL_RX, 2); IOConfigGPIO(IOGetByTag(IO_TAG(PA3)), IOCFG_IPU); } } // RX/TX Interrupt NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART2); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART2); NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); return s; }
#define I2C1_SDA PB7 #endif #ifndef I2C2_SCL #define I2C2_SCL PF4 #endif #ifndef I2C2_SDA #define I2C2_SDA PA10 #endif static uint32_t i2cTimeout; static volatile uint16_t i2cErrorCount = 0; //static volatile uint16_t i2c2ErrorCount = 0; static i2cDevice_t i2cHardwareMap[] = { { .dev = I2C1, .scl = IO_TAG(I2C1_SCL), .sda = IO_TAG(I2C1_SDA), .rcc = RCC_APB1(I2C1), .overClock = I2C1_OVERCLOCK }, { .dev = I2C2, .scl = IO_TAG(I2C2_SCL), .sda = IO_TAG(I2C2_SDA), .rcc = RCC_APB1(I2C2), .overClock = I2C2_OVERCLOCK } }; /////////////////////////////////////////////////////////////////////////////// // I2C TimeoutUserCallback /////////////////////////////////////////////////////////////////////////////// uint32_t i2cTimeoutUserCallback(void) { i2cErrorCount++; return false; } void i2cInit(I2CDevice device) {
#ifndef I2C3_SCL #define I2C3_SCL PA8 #endif #ifndef I2C3_SDA #define I2C3_SDA PB4 #endif #ifndef I2C4_SCL #define I2C4_SCL PD12 #endif #ifndef I2C4_SDA #define I2C4_SDA PD13 #endif static i2cDevice_t i2cHardwareMap[] = { { .dev = I2C1, .scl = IO_TAG(I2C1_SCL), .sda = IO_TAG(I2C1_SDA), .rcc = RCC_APB1(I2C1), .overClock = I2C1_OVERCLOCK, .ev_irq = I2C1_EV_IRQn, .er_irq = I2C1_ER_IRQn, .af = GPIO_AF4_I2C1 }, { .dev = I2C2, .scl = IO_TAG(I2C2_SCL), .sda = IO_TAG(I2C2_SDA), .rcc = RCC_APB1(I2C2), .overClock = I2C2_OVERCLOCK, .ev_irq = I2C2_EV_IRQn, .er_irq = I2C2_ER_IRQn, .af = GPIO_AF4_I2C2 }, { .dev = I2C3, .scl = IO_TAG(I2C3_SCL), .sda = IO_TAG(I2C3_SDA), .rcc = RCC_APB1(I2C3), .overClock = I2C2_OVERCLOCK, .ev_irq = I2C3_EV_IRQn, .er_irq = I2C3_ER_IRQn, .af = GPIO_AF4_I2C3 }, { .dev = I2C4, .scl = IO_TAG(I2C4_SCL), .sda = IO_TAG(I2C4_SDA), .rcc = RCC_APB1(I2C4), .overClock = I2C2_OVERCLOCK, .ev_irq = I2C4_EV_IRQn, .er_irq = I2C4_ER_IRQn, .af = GPIO_AF4_I2C4 } }; typedef struct { I2C_HandleTypeDef Handle; } i2cHandle_t; static i2cHandle_t i2cHandle[I2CDEV_MAX+1]; void I2C1_ER_IRQHandler(void) { HAL_I2C_ER_IRQHandler(&i2cHandle[I2CDEV_1].Handle); }
* * You should have received a copy of the GNU General Public License * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>. */ #include <platform.h> #include "common/utils.h" #include "stm32f10x.h" #include "rcc.h" #include "timer.h" const timerDef_t timerDefinitions[HARDWARE_TIMER_DEFINITION_COUNT] = { { .TIMx = TIM1, .rcc = RCC_APB2(TIM1), .inputIrq = TIM1_CC_IRQn }, { .TIMx = TIM2, .rcc = RCC_APB1(TIM2), .inputIrq = TIM2_IRQn }, { .TIMx = TIM3, .rcc = RCC_APB1(TIM3), .inputIrq = TIM3_IRQn }, { .TIMx = TIM4, .rcc = RCC_APB1(TIM4), .inputIrq = TIM4_IRQn }, #if defined(STM32F10X_HD) || defined(STM32F10X_CL) || defined(STM32F10X_XL) || defined(STM32F10X_HD_VL) { .TIMx = TIM5, .rcc = RCC_APB1(TIM5), .inputIrq = TIM5_IRQn }, { .TIMx = TIM6, .rcc = RCC_APB1(TIM6), .inputIrq = 0 }, { .TIMx = TIM7, .rcc = RCC_APB1(TIM7), .inputIrq = 0 }, #endif #if defined(STM32F10X_XL) || defined(STM32F10X_HD_VL) { .TIMx = TIM8, .rcc = RCC_APB1(TIM8), .inputIrq = TIM8_CC_IRQn }, { .TIMx = TIM9, .rcc = RCC_APB2(TIM9), .inputIrq = TIM1_BRK_TIM9_IRQn }, { .TIMx = TIM10, .rcc = RCC_APB2(TIM10), .inputIrq = TIM1_UP_TIM10_IRQn }, { .TIMx = TIM11, .rcc = RCC_APB2(TIM11), .inputIrq = TIM1_TRG_COM_TIM11_IRQn }, { .TIMx = TIM12, .rcc = RCC_APB1(TIM12), .inputIrq = TIM12_IRQn }, { .TIMx = TIM13, .rcc = RCC_APB1(TIM13), .inputIrq = TIM13_IRQn }, { .TIMx = TIM14, .rcc = RCC_APB1(TIM14), .inputIrq = TIM14_IRQn },
* * You should have received a copy of the GNU General Public License * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>. */ #include "platform.h" #include "common/utils.h" #include "stm32f4xx.h" #include "rcc.h" #include "timer.h" const timerDef_t timerDefinitions[HARDWARE_TIMER_DEFINITION_COUNT] = { { .TIMx = TIM1, .rcc = RCC_APB2(TIM1), .inputIrq = TIM1_CC_IRQn}, { .TIMx = TIM2, .rcc = RCC_APB1(TIM2), .inputIrq = TIM2_IRQn}, { .TIMx = TIM3, .rcc = RCC_APB1(TIM3), .inputIrq = TIM3_IRQn}, { .TIMx = TIM4, .rcc = RCC_APB1(TIM4), .inputIrq = TIM4_IRQn}, { .TIMx = TIM5, .rcc = RCC_APB1(TIM5), .inputIrq = TIM5_IRQn}, { .TIMx = TIM6, .rcc = RCC_APB1(TIM6), .inputIrq = 0}, { .TIMx = TIM7, .rcc = RCC_APB1(TIM7), .inputIrq = 0}, #if !defined(STM32F411xE) && !defined(STM32F446xx) { .TIMx = TIM8, .rcc = RCC_APB2(TIM8), .inputIrq = TIM8_CC_IRQn}, #endif { .TIMx = TIM9, .rcc = RCC_APB2(TIM9), .inputIrq = TIM1_BRK_TIM9_IRQn}, { .TIMx = TIM10, .rcc = RCC_APB2(TIM10), .inputIrq = TIM1_UP_TIM10_IRQn}, { .TIMx = TIM11, .rcc = RCC_APB2(TIM11), .inputIrq = TIM1_TRG_COM_TIM11_IRQn}, #ifndef STM32F411xE { .TIMx = TIM12, .rcc = RCC_APB1(TIM12), .inputIrq = TIM8_BRK_TIM12_IRQn}, { .TIMx = TIM13, .rcc = RCC_APB1(TIM13), .inputIrq = TIM8_UP_TIM13_IRQn}, { .TIMx = TIM14, .rcc = RCC_APB1(TIM14), .inputIrq = TIM8_TRG_COM_TIM14_IRQn},
#ifndef I2C2_SDA #define I2C2_SDA PB11 #endif #ifdef STM32F4 #ifndef I2C3_SCL #define I2C3_SCL PA8 #endif #ifndef I2C3_SDA #define I2C3_SDA PB4 #endif #endif static i2cDevice_t i2cHardwareMap[] = { { .dev = I2C1, .scl = IO_TAG(I2C1_SCL), .sda = IO_TAG(I2C1_SDA), .rcc = RCC_APB1(I2C1), .overClock = I2C1_OVERCLOCK, .ev_irq = I2C1_EV_IRQn, .er_irq = I2C1_ER_IRQn }, { .dev = I2C2, .scl = IO_TAG(I2C2_SCL), .sda = IO_TAG(I2C2_SDA), .rcc = RCC_APB1(I2C2), .overClock = I2C2_OVERCLOCK, .ev_irq = I2C2_EV_IRQn, .er_irq = I2C2_ER_IRQn }, #ifdef STM32F4 { .dev = I2C3, .scl = IO_TAG(I2C3_SCL), .sda = IO_TAG(I2C3_SDA), .rcc = RCC_APB1(I2C3), .overClock = I2C2_OVERCLOCK, .ev_irq = I2C3_EV_IRQn, .er_irq = I2C3_ER_IRQn } #endif }; static volatile uint16_t i2cErrorCount = 0; static i2cState_t i2cState[] = { { false, false, 0, 0, 0, 0, 0, 0, 0 }, { false, false, 0, 0, 0, 0, 0, 0, 0 }, { false, false, 0, 0, 0, 0, 0, 0, 0 } }; void I2C1_ER_IRQHandler(void) {
{ .device = SPIDEV_2, .reg = SPI2, .sckPins = { { DEFIO_TAG_E(PB13) }, // { DEFIO_TAG_E(PB3) }, }, .misoPins = { { DEFIO_TAG_E(PB14) }, // { DEFIO_TAG_E(PB4) }, }, .mosiPins = { { DEFIO_TAG_E(PB15) }, // { DEFIO_TAG_E(PB5) }, }, .rcc = RCC_APB1(SPI2), }, #endif #ifdef STM32F3 #ifndef GPIO_AF_SPI1 #define GPIO_AF_SPI1 GPIO_AF_5 #endif #ifndef GPIO_AF_SPI2 #define GPIO_AF_SPI2 GPIO_AF_5 #endif #ifndef GPIO_AF_SPI3 #define GPIO_AF_SPI3 GPIO_AF_6 #endif {
#define SPI1_NSS_PIN NONE #endif #ifndef SPI2_NSS_PIN #define SPI2_NSS_PIN NONE #endif #ifndef SPI3_NSS_PIN #define SPI3_NSS_PIN NONE #endif #ifndef SPI4_NSS_PIN #define SPI4_NSS_PIN NONE #endif static spiDevice_t spiHardwareMap[] = { { .dev = SPI1, .nss = IO_TAG(SPI1_NSS_PIN), .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .af = GPIO_AF5_SPI1, false }, { .dev = SPI2, .nss = IO_TAG(SPI2_NSS_PIN), .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1(SPI2), .af = GPIO_AF5_SPI2, false }, { .dev = SPI3, .nss = IO_TAG(SPI3_NSS_PIN), .sck = IO_TAG(SPI3_SCK_PIN), .miso = IO_TAG(SPI3_MISO_PIN), .mosi = IO_TAG(SPI3_MOSI_PIN), .rcc = RCC_APB1(SPI3), .af = GPIO_AF5_SPI3, false }, { .dev = SPI4, .nss = IO_TAG(SPI4_NSS_PIN), .sck = IO_TAG(SPI4_SCK_PIN), .miso = IO_TAG(SPI4_MISO_PIN), .mosi = IO_TAG(SPI4_MOSI_PIN), .rcc = RCC_APB2(SPI4), .af = GPIO_AF5_SPI4, false } }; typedef struct{ SPI_HandleTypeDef Handle; }spiHandle_t; static spiHandle_t spiHandle[SPIDEV_MAX+1]; typedef struct{ DMA_HandleTypeDef Handle; }dmaHandle_t; static dmaHandle_t dmaHandle[SPIDEV_MAX+1]; SPIDevice spiDeviceByInstance(SPI_TypeDef *instance)
#define SPI1_NSS_PIN NONE #endif #ifndef SPI2_NSS_PIN #define SPI2_NSS_PIN NONE #endif #ifndef SPI3_NSS_PIN #define SPI3_NSS_PIN NONE #endif #ifndef SPI4_NSS_PIN #define SPI4_NSS_PIN NONE #endif static spiDevice_t spiHardwareMap[] = { { .dev = SPI1, .nss = IO_TAG(SPI1_NSS_PIN), .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .af = GPIO_AF5_SPI1, .leadingEdge = false, .dmaIrqHandler = DMA2_ST3_HANDLER }, { .dev = SPI2, .nss = IO_TAG(SPI2_NSS_PIN), .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1(SPI2), .af = GPIO_AF5_SPI2, .leadingEdge = false, .dmaIrqHandler = DMA1_ST4_HANDLER }, { .dev = SPI3, .nss = IO_TAG(SPI3_NSS_PIN), .sck = IO_TAG(SPI3_SCK_PIN), .miso = IO_TAG(SPI3_MISO_PIN), .mosi = IO_TAG(SPI3_MOSI_PIN), .rcc = RCC_APB1(SPI3), .af = GPIO_AF6_SPI3, .leadingEdge = false, .dmaIrqHandler = DMA1_ST7_HANDLER }, { .dev = SPI4, .nss = IO_TAG(SPI4_NSS_PIN), .sck = IO_TAG(SPI4_SCK_PIN), .miso = IO_TAG(SPI4_MISO_PIN), .mosi = IO_TAG(SPI4_MOSI_PIN), .rcc = RCC_APB2(SPI4), .af = GPIO_AF5_SPI4, .leadingEdge = false, .dmaIrqHandler = DMA2_ST1_HANDLER } }; SPIDevice spiDeviceByInstance(SPI_TypeDef *instance) { if (instance == SPI1) return SPIDEV_1; if (instance == SPI2) return SPIDEV_2; if (instance == SPI3) return SPIDEV_3;
static void i2cUnstick(IO_t scl, IO_t sda); #define IOCFG_I2C_PU IO_CONFIG(GPIO_MODE_AF_OD, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_PULLUP) #define IOCFG_I2C IO_CONFIG(GPIO_MODE_AF_OD, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_NOPULL) #define GPIO_AF4_I2C GPIO_AF4_I2C1 const i2cHardware_t i2cHardware[I2CDEV_COUNT] = { #ifdef USE_I2C_DEVICE_1 { .device = I2CDEV_1, .reg = I2C1, .sclPins = { I2CPINDEF(PB6), I2CPINDEF(PB8) }, .sdaPins = { I2CPINDEF(PB7), I2CPINDEF(PB9) }, .rcc = RCC_APB1(I2C1), .ev_irq = I2C1_EV_IRQn, .er_irq = I2C1_ER_IRQn, }, #endif #ifdef USE_I2C_DEVICE_2 { .device = I2CDEV_2, .reg = I2C2, .sclPins = { I2CPINDEF(PB10), I2CPINDEF(PF1) }, .sdaPins = { I2CPINDEF(PB11), I2CPINDEF(PF0) }, .rcc = RCC_APB1(I2C2), .ev_irq = I2C2_EV_IRQn, .er_irq = I2C2_ER_IRQn, }, #endif