serialPort_t *uartOpen(USART_TypeDef *USARTx, serialReceiveCallbackPtr callback, uint32_t baudRate, portMode_t mode) { DMA_InitTypeDef DMA_InitStructure; USART_InitTypeDef USART_InitStructure; uartPort_t *s = NULL; if (USARTx == USART1) s = serialUSART1(baudRate, mode); if (USARTx == USART2) s = serialUSART2(baudRate, mode); s->USARTx = USARTx; // common serial initialisation code should move to serialPort::init() s->port.rxBufferHead = s->port.rxBufferTail = 0; s->port.txBufferHead = s->port.txBufferTail = 0; // callback for IRQ-based RX ONLY s->port.callback = callback; s->port.mode = mode; s->port.baudRate = baudRate; USART_InitStructure.USART_BaudRate = baudRate; USART_InitStructure.USART_WordLength = USART_WordLength_8b; if (mode & MODE_SBUS) { USART_InitStructure.USART_StopBits = USART_StopBits_2; USART_InitStructure.USART_Parity = USART_Parity_Even; } else { USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; } USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = 0; if (mode & MODE_RX) USART_InitStructure.USART_Mode |= USART_Mode_Rx; if (mode & MODE_TX) USART_InitStructure.USART_Mode |= USART_Mode_Tx; USART_Init(USARTx, &USART_InitStructure); USART_Cmd(USARTx, ENABLE); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USARTx->DR; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // Receive DMA or IRQ if (mode & MODE_RX) { if (s->rxDMAChannel) { DMA_InitStructure.DMA_BufferSize = s->port.rxBufferSize; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)s->port.rxBuffer; DMA_DeInit(s->rxDMAChannel); DMA_Init(s->rxDMAChannel, &DMA_InitStructure); DMA_Cmd(s->rxDMAChannel, ENABLE); USART_DMACmd(USARTx, USART_DMAReq_Rx, ENABLE); s->rxDMAPos = DMA_GetCurrDataCounter(s->rxDMAChannel); } else { USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); } } // Transmit DMA or IRQ if (mode & MODE_TX) { if (s->txDMAChannel) { DMA_InitStructure.DMA_BufferSize = s->port.txBufferSize; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_DeInit(s->txDMAChannel); DMA_Init(s->txDMAChannel, &DMA_InitStructure); DMA_ITConfig(s->txDMAChannel, DMA_IT_TC, ENABLE); DMA_SetCurrDataCounter(s->txDMAChannel, 0); s->txDMAChannel->CNDTR = 0; USART_DMACmd(USARTx, USART_DMAReq_Tx, ENABLE); } else { USART_ITConfig(USARTx, USART_IT_TXE, ENABLE); } } return (serialPort_t *)s; }
serialPort_t *uartOpen(USART_TypeDef *USARTx, serialReceiveCallbackPtr callback, uint32_t baudRate, portMode_t mode, serialInversion_e inversion) { uartPort_t *s = NULL; if (USARTx == USART1) { s = serialUSART1(baudRate, mode); #ifdef USE_USART2 } else if (USARTx == USART2) { s = serialUSART2(baudRate, mode); #endif #ifdef USE_USART3 } else if (USARTx == USART3) { s = serialUSART3(baudRate, mode); #endif } else { return (serialPort_t *)s; } s->txDMAEmpty = true; // common serial initialisation code should move to serialPort::init() s->port.rxBufferHead = s->port.rxBufferTail = 0; s->port.txBufferHead = s->port.txBufferTail = 0; // callback works for IRQ-based RX ONLY s->port.callback = callback; s->port.mode = mode; s->port.baudRate = baudRate; s->port.inversion = inversion; uartReconfigure(s); // Receive DMA or IRQ DMA_InitTypeDef DMA_InitStructure; if ((mode & MODE_RX) || (mode & MODE_BIDIR)) { if (s->rxDMAChannel) { DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = s->rxDMAPeripheralBaseAddr; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_BufferSize = s->port.rxBufferSize; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)s->port.rxBuffer; DMA_DeInit(s->rxDMAChannel); DMA_Init(s->rxDMAChannel, &DMA_InitStructure); DMA_Cmd(s->rxDMAChannel, ENABLE); USART_DMACmd(s->USARTx, USART_DMAReq_Rx, ENABLE); s->rxDMAPos = DMA_GetCurrDataCounter(s->rxDMAChannel); } else { USART_ClearITPendingBit(s->USARTx, USART_IT_RXNE); USART_ITConfig(s->USARTx, USART_IT_RXNE, ENABLE); } } // Transmit DMA or IRQ if ((mode & MODE_TX) || (mode & MODE_BIDIR)) { if (s->txDMAChannel) { DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = s->txDMAPeripheralBaseAddr; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_BufferSize = s->port.txBufferSize; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_DeInit(s->txDMAChannel); DMA_Init(s->txDMAChannel, &DMA_InitStructure); DMA_ITConfig(s->txDMAChannel, DMA_IT_TC, ENABLE); DMA_SetCurrDataCounter(s->txDMAChannel, 0); s->txDMAChannel->CNDTR = 0; USART_DMACmd(s->USARTx, USART_DMAReq_Tx, ENABLE); } else { USART_ITConfig(s->USARTx, USART_IT_TXE, ENABLE); } } USART_Cmd(s->USARTx, ENABLE); if (mode & MODE_BIDIR) USART_HalfDuplexCmd(s->USARTx, ENABLE); else USART_HalfDuplexCmd(s->USARTx, DISABLE); return (serialPort_t *)s; }
serialPort_t *serialOpen(USART_TypeDef * USARTx, uint32_t baudRate) { DMA_InitTypeDef DMA_InitStructure; USART_InitTypeDef USART_InitStructure; serialPort_t *s = NULL; if (USARTx == USART1) s = serialUSART1(baudRate); if (USARTx == USART2) s = serialUSART2(baudRate); if (USARTx == USART3) s = serialUSART3(baudRate); s->USARTx = USARTx; s->rxBufferHead = s->rxBufferTail = 0; s->txBufferHead = s->txBufferTail = 0; USART_InitStructure.USART_BaudRate = baudRate; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USARTx, &USART_InitStructure); USART_Cmd(USARTx, ENABLE); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & USARTx->DR; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // Receive DMA into a circular buffer if (s->rxDMAChannel) { DMA_InitStructure.DMA_BufferSize = s->rxBufferSize; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) s->rxBuffer; DMA_DeInit(s->rxDMAChannel); DMA_Init(s->rxDMAChannel, &DMA_InitStructure); DMA_Cmd(s->rxDMAChannel, ENABLE); USART_DMACmd(USARTx, USART_DMAReq_Rx, ENABLE); s->rxDMAPos = DMA_GetCurrDataCounter(s->rxDMAChannel); } else { USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); } // Transmit DMA if (s->txDMAChannel) { DMA_InitStructure.DMA_BufferSize = s->txBufferSize; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_DeInit(s->txDMAChannel); DMA_Init(s->txDMAChannel, &DMA_InitStructure); DMA_ITConfig(s->txDMAChannel, DMA_IT_TC, ENABLE); DMA_SetCurrDataCounter(s->txDMAChannel, 0); s->txDMAChannel->CNDTR = 0; USART_DMACmd(USARTx, USART_DMAReq_Tx, ENABLE); } else { USART_ITConfig(USARTx, USART_IT_TXE, ENABLE); } return s; }
serialPort_t *serialOpen(USART_TypeDef *USARTx, unsigned int baud, uint16_t flowControl, unsigned int rxBufSize, unsigned int txBufSize) { DMA_InitTypeDef DMA_InitStructure; serialPort_t *s = 0; // Enable USART clocks/ports #ifdef SERIAL_UART1_PORT if (USARTx == USART1) { s = serialUSART1(flowControl, rxBufSize, txBufSize); } #endif #ifdef SERIAL_UART2_PORT if (USARTx == USART2) { s = serialUSART2(flowControl, rxBufSize, txBufSize); } #endif #ifdef SERIAL_UART3_PORT if (USARTx == USART3) { s = serialUSART3(flowControl, rxBufSize, txBufSize); } #endif #ifdef SERIAL_UART4_PORT if (USARTx == UART4) { s = serialUSART4(flowControl, rxBufSize, txBufSize); } #endif #ifdef SERIAL_UART5_PORT if (USARTx == UART5) { s = serialUSART5(flowControl, rxBufSize, txBufSize); } #endif #ifdef SERIAL_UART6_PORT if (USARTx == USART6) { s = serialUSART6(flowControl, rxBufSize, txBufSize); } #endif s->waitFlag = CoCreateFlag(0, 0); // manual reset s->USARTx = USARTx; s->rxHead = s->rxTail = 0; s->txHead = s->txTail = 0; s->baudRate = baud; s->flowControl = flowControl; s->parity = USART_Parity_No; s->stopBits = USART_StopBits_1; serialOpenUART(s); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)USARTx + 0x04; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Priority = DMA_Priority_Low; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; // Configure DMA for rx if (s->rxDMAStream) { DMA_DeInit(s->rxDMAStream); DMA_InitStructure.DMA_Channel = s->rxDMAChannel; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)s->rxBuf; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = s->rxBufSize; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(s->rxDMAStream, &DMA_InitStructure); DMA_ClearFlag(s->rxDMAStream, s->rxDmaFlags); DMA_Cmd(s->rxDMAStream, ENABLE); USART_DMACmd(USARTx, USART_DMAReq_Rx, ENABLE); s->rxPos = DMA_GetCurrDataCounter(s->rxDMAStream); } // otherwise use ISR else { USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); } // Configure DMA for tx if (s->txDMAStream) { DMA_DeInit(s->txDMAStream); DMA_InitStructure.DMA_Channel = s->txDMAChannel; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_BufferSize = (s->txBufSize != 0) ? s->txBufSize : 16; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(s->txDMAStream, &DMA_InitStructure); DMA_SetCurrDataCounter(s->txDMAStream, 0); DMA_ITConfig(s->txDMAStream, DMA_IT_TC, ENABLE); USART_DMACmd(USARTx, USART_DMAReq_Tx, ENABLE); } // otherwise use ISR else { USART_ITConfig(USARTx, USART_IT_TXE, ENABLE); } // use this port for STDIO if not already defined if (serialSTDIO == 0) serialSTDIO = s; return s; }
serialPort_t *uartOpen(USART_TypeDef *USARTx, serialReceiveCallbackPtr callback, uint32_t baudRate, portMode_t mode, portOptions_t options) { uartPort_t *s = NULL; if (USARTx == USART1) { s = serialUSART1(baudRate, mode, options); #ifdef USE_USART2 } else if (USARTx == USART2) { s = serialUSART2(baudRate, mode, options); #endif #ifdef USE_USART3 } else if (USARTx == USART3) { s = serialUSART3(baudRate, mode, options); #endif #ifdef USE_USART4 } else if (USARTx == UART4) { s = serialUSART4(baudRate, mode, options); #endif #ifdef USE_USART5 } else if (USARTx == UART5) { s = serialUSART5(baudRate, mode, options); #endif #ifdef USE_USART6 } else if (USARTx == USART6) { s = serialUSART6(baudRate, mode, options); #endif } else { return (serialPort_t *)s; } s->txDMAEmpty = true; // common serial initialisation code should move to serialPort::init() s->port.rxBufferHead = s->port.rxBufferTail = 0; s->port.txBufferHead = s->port.txBufferTail = 0; // callback works for IRQ-based RX ONLY s->port.callback = callback; s->port.mode = mode; s->port.baudRate = baudRate; s->port.options = options; uartReconfigure(s); // Receive DMA or IRQ DMA_InitTypeDef DMA_InitStructure; if (mode & MODE_RX) { #ifdef STM32F40_41xxx if (s->rxDMAStream) { DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = s->rxDMAPeripheralBaseAddr; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable ; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull ; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single ; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; #else if (s->rxDMAChannel) { DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = s->rxDMAPeripheralBaseAddr; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; #endif DMA_InitStructure.DMA_BufferSize = s->port.rxBufferSize; #ifdef STM32F40_41xxx DMA_InitStructure.DMA_Channel = s->rxDMAChannel; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)s->port.rxBuffer; DMA_DeInit(s->rxDMAStream); DMA_Init(s->rxDMAStream, &DMA_InitStructure); DMA_Cmd(s->rxDMAStream, ENABLE); USART_DMACmd(s->USARTx, USART_DMAReq_Rx, ENABLE); s->rxDMAPos = DMA_GetCurrDataCounter(s->rxDMAStream); #else DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)s->port.rxBuffer; DMA_DeInit(s->rxDMAChannel); DMA_Init(s->rxDMAChannel, &DMA_InitStructure); DMA_Cmd(s->rxDMAChannel, ENABLE); USART_DMACmd(s->USARTx, USART_DMAReq_Rx, ENABLE); s->rxDMAPos = DMA_GetCurrDataCounter(s->rxDMAChannel); #endif } else { USART_ClearITPendingBit(s->USARTx, USART_IT_RXNE); USART_ITConfig(s->USARTx, USART_IT_RXNE, ENABLE); } } // Transmit DMA or IRQ if (mode & MODE_TX) { #ifdef STM32F40_41xxx if (s->txDMAStream) { DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = s->txDMAPeripheralBaseAddr; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable ; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull ; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single ; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; #else if (s->txDMAChannel) { DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = s->txDMAPeripheralBaseAddr; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; #endif DMA_InitStructure.DMA_BufferSize = s->port.txBufferSize; #ifdef STM32F40_41xxx DMA_InitStructure.DMA_Channel = s->txDMAChannel; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_DeInit(s->txDMAStream); DMA_Init(s->txDMAStream, &DMA_InitStructure); DMA_ITConfig(s->txDMAStream, DMA_IT_TC|DMA_IT_FE|DMA_IT_TE|DMA_IT_DME, ENABLE); DMA_SetCurrDataCounter(s->txDMAStream, 0); #else DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_DeInit(s->txDMAChannel); DMA_Init(s->txDMAChannel, &DMA_InitStructure); DMA_ITConfig(s->txDMAChannel, DMA_IT_TC, ENABLE); DMA_SetCurrDataCounter(s->txDMAChannel, 0); s->txDMAChannel->CNDTR = 0; #endif USART_DMACmd(s->USARTx, USART_DMAReq_Tx, ENABLE); } else { USART_ITConfig(s->USARTx, USART_IT_TXE, ENABLE); } } USART_Cmd(s->USARTx, ENABLE); return (serialPort_t *)s; } void uartSetBaudRate(serialPort_t *instance, uint32_t baudRate) { uartPort_t *uartPort = (uartPort_t *)instance; uartPort->port.baudRate = baudRate; uartReconfigure(uartPort); } void uartSetMode(serialPort_t *instance, portMode_t mode) { uartPort_t *uartPort = (uartPort_t *)instance; uartPort->port.mode = mode; uartReconfigure(uartPort); }