Skip to content

Commit

Permalink
Merge pull request #4717 from gebart/pr/stm32f4-uart-lock
Browse files Browse the repository at this point in the history
cpu/stm32f4: Fix DMA race bug (#4716)
  • Loading branch information
Joakim Nohlgård committed Feb 1, 2016
2 parents fc475dd + 4fd7f23 commit fa273b1
Showing 1 changed file with 10 additions and 6 deletions.
16 changes: 10 additions & 6 deletions cpu/stm32f4/periph/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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]);
}
}

Expand Down Expand Up @@ -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();
}
Expand Down

0 comments on commit fa273b1

Please sign in to comment.