mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #4717 from gebart/pr/stm32f4-uart-lock
cpu/stm32f4: Fix DMA race bug (#4716)
This commit is contained in:
commit
fa273b134e
@ -42,7 +42,8 @@ static inline USART_TypeDef *_dev(uart_t uart)
|
||||
/**
|
||||
* @brief Transmission locks
|
||||
*/
|
||||
static mutex_t tx_sync[UART_NUMOF];
|
||||
static mutex_t _tx_dma_sync[UART_NUMOF];
|
||||
static mutex_t _tx_lock[UART_NUMOF];
|
||||
|
||||
/**
|
||||
* @brief Find out which peripheral bus the UART device is connected to
|
||||
@ -73,9 +74,10 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
|
||||
/* remember callback addresses and argument */
|
||||
uart_ctx[uart].rx_cb = rx_cb;
|
||||
uart_ctx[uart].arg = arg;
|
||||
/* init tx lock */
|
||||
mutex_init(&tx_sync[uart]);
|
||||
mutex_lock(&tx_sync[uart]);
|
||||
/* init TX lock and DMA synchronization mutex */
|
||||
mutex_init(&_tx_lock[uart]);
|
||||
mutex_init(&_tx_dma_sync[uart]);
|
||||
mutex_lock(&_tx_dma_sync[uart]);
|
||||
|
||||
/* configure pins */
|
||||
gpio_init(uart_config[uart].rx_pin, GPIO_DIR_IN, GPIO_NOPULL);
|
||||
@ -128,13 +130,15 @@ void uart_write(uart_t uart, const uint8_t *data, size_t len)
|
||||
}
|
||||
}
|
||||
else {
|
||||
mutex_lock(&_tx_lock[uart]);
|
||||
DMA_Stream_TypeDef *stream = dma_stream(uart_config[uart].dma_stream);
|
||||
/* configure and start DMA transfer */
|
||||
stream->M0AR = (uint32_t)data;
|
||||
stream->NDTR = (uint16_t)len;
|
||||
stream->CR |= DMA_SxCR_EN;
|
||||
/* wait for transfer to complete */
|
||||
mutex_lock(&tx_sync[uart]);
|
||||
mutex_lock(&_tx_dma_sync[uart]);
|
||||
mutex_unlock(&_tx_lock[uart]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,7 +177,7 @@ static inline void dma_handler(int uart, int stream)
|
||||
{
|
||||
/* clear DMA done flag */
|
||||
dma_base(stream)->IFCR[dma_hl(stream)] = dma_ifc(stream);
|
||||
mutex_unlock(&tx_sync[uart]);
|
||||
mutex_unlock(&_tx_dma_sync[uart]);
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user