mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +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
|
* @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
|
* @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 */
|
/* remember callback addresses and argument */
|
||||||
uart_ctx[uart].rx_cb = rx_cb;
|
uart_ctx[uart].rx_cb = rx_cb;
|
||||||
uart_ctx[uart].arg = arg;
|
uart_ctx[uart].arg = arg;
|
||||||
/* init tx lock */
|
/* init TX lock and DMA synchronization mutex */
|
||||||
mutex_init(&tx_sync[uart]);
|
mutex_init(&_tx_lock[uart]);
|
||||||
mutex_lock(&tx_sync[uart]);
|
mutex_init(&_tx_dma_sync[uart]);
|
||||||
|
mutex_lock(&_tx_dma_sync[uart]);
|
||||||
|
|
||||||
/* configure pins */
|
/* configure pins */
|
||||||
gpio_init(uart_config[uart].rx_pin, GPIO_DIR_IN, GPIO_NOPULL);
|
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 {
|
else {
|
||||||
|
mutex_lock(&_tx_lock[uart]);
|
||||||
DMA_Stream_TypeDef *stream = dma_stream(uart_config[uart].dma_stream);
|
DMA_Stream_TypeDef *stream = dma_stream(uart_config[uart].dma_stream);
|
||||||
/* configure and start DMA transfer */
|
/* configure and start DMA transfer */
|
||||||
stream->M0AR = (uint32_t)data;
|
stream->M0AR = (uint32_t)data;
|
||||||
stream->NDTR = (uint16_t)len;
|
stream->NDTR = (uint16_t)len;
|
||||||
stream->CR |= DMA_SxCR_EN;
|
stream->CR |= DMA_SxCR_EN;
|
||||||
/* wait for transfer to complete */
|
/* 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 */
|
/* clear DMA done flag */
|
||||||
dma_base(stream)->IFCR[dma_hl(stream)] = dma_ifc(stream);
|
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) {
|
if (sched_context_switch_request) {
|
||||||
thread_yield();
|
thread_yield();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user