From 94cb28e5628b762665c350c425721bfa9a091b4c Mon Sep 17 00:00:00 2001 From: Raman Date: Mon, 14 Jan 2019 08:02:38 +0530 Subject: [PATCH] XMC47: eLua serial console: Enable DMA mode for UART0 --- src/platform/xmc4000/platform.c | 14 +++ .../xmc4000/xmclib/gen/UART/uart_conf.c | 111 +++++++++++++++--- .../xmc4000/xmclib/gen/UART/uart_conf.h | 4 +- .../xmc4000/xmclib/gen/UART/uart_extern.h | 2 + 4 files changed, 113 insertions(+), 18 deletions(-) diff --git a/src/platform/xmc4000/platform.c b/src/platform/xmc4000/platform.c index 4316bdbb..bc16f62c 100644 --- a/src/platform/xmc4000/platform.c +++ b/src/platform/xmc4000/platform.c @@ -178,14 +178,28 @@ timer_data_type platform_s_timer_op( unsigned id, int op,timer_data_type data ) // **************************************************************************** // UART +void elua_uart_rx_callback( void ) +{ + // Empty for now. +} + +void elua_uart_tx_callback( void ) +{ + // Empty for now. +} + void platform_s_uart_send( unsigned id, u8 data ) { + // Internally invokes DMA for transmit UART_Transmit( &UART_0, &data, 1 ); + while( UART_0.runtime->tx_busy ); } int platform_s_uart_recv( unsigned id, timer_data_type timeout ) { + // Internally invokes DMA for receive UART_Receive( &UART_0, &recv_byte, 1 ); + while( UART_0.runtime->rx_busy ); return recv_byte; } diff --git a/src/platform/xmc4000/xmclib/gen/UART/uart_conf.c b/src/platform/xmc4000/xmclib/gen/UART/uart_conf.c index 62248889..66fc992a 100644 --- a/src/platform/xmc4000/xmclib/gen/UART/uart_conf.c +++ b/src/platform/xmc4000/xmclib/gen/UART/uart_conf.c @@ -75,6 +75,8 @@ extern void UART_lProtocolHandler(const UART_t * const handle); * DATA STRUCTURES **********************************************************************************************************************/ UART_STATUS_t UART_0_init(void); +void UART_0_dma_tx_handler(XMC_DMA_CH_EVENT_t event); +void UART_0_dma_rx_handler(XMC_DMA_CH_EVENT_t event); /*USIC channel configuration*/ const XMC_UART_CH_CONFIG_t UART_0_channel_config = @@ -102,12 +104,56 @@ const UART_TX_CONFIG_t UART_0_tx_pin = .pin = 5U }; +const XMC_DMA_CH_CONFIG_t UART_0_tx_dma_ch_config = +{ + .enable_interrupt = true, + .dst_transfer_width = (uint32_t)XMC_DMA_CH_TRANSFER_WIDTH_8, + .src_transfer_width = (uint32_t)XMC_DMA_CH_TRANSFER_WIDTH_8, + .dst_address_count_mode = (uint32_t)XMC_DMA_CH_ADDRESS_COUNT_MODE_NO_CHANGE, + .src_address_count_mode = (uint32_t)XMC_DMA_CH_ADDRESS_COUNT_MODE_INCREMENT, + .dst_burst_length = (uint32_t)XMC_DMA_CH_BURST_LENGTH_1, + .src_burst_length = (uint32_t)XMC_DMA_CH_BURST_LENGTH_8, + .transfer_flow = (uint32_t)XMC_DMA_CH_TRANSFER_FLOW_M2P_DMA, + .transfer_type = (uint32_t)XMC_DMA_CH_TRANSFER_TYPE_SINGLE_BLOCK, + .dst_handshaking = (uint32_t)XMC_DMA_CH_DST_HANDSHAKING_HARDWARE, + .dst_peripheral_request = DMA_PERIPHERAL_REQUEST(5U, 10U), /*DMA0_PERIPHERAL_REQUEST_USIC0_SR0_5*/ +}; + +const UART_DMA_CONFIG_t UART_0_tx_dma_config = +{ + .dma_ch_config = &UART_0_tx_dma_ch_config, + .dma_channel = 5U +}; + +const XMC_DMA_CH_CONFIG_t UART_0_rx_dma_ch_config = +{ + .enable_interrupt = true, + .dst_transfer_width = (uint32_t)XMC_DMA_CH_TRANSFER_WIDTH_8, + .src_transfer_width = (uint32_t)XMC_DMA_CH_TRANSFER_WIDTH_8, + .dst_address_count_mode = (uint32_t)XMC_DMA_CH_ADDRESS_COUNT_MODE_INCREMENT, + .src_address_count_mode = (uint32_t)XMC_DMA_CH_ADDRESS_COUNT_MODE_NO_CHANGE, + .dst_burst_length = (uint32_t)XMC_DMA_CH_BURST_LENGTH_8, + .src_burst_length = (uint32_t)XMC_DMA_CH_BURST_LENGTH_1, + .transfer_flow = (uint32_t)XMC_DMA_CH_TRANSFER_FLOW_P2M_DMA, + .transfer_type = (uint32_t)XMC_DMA_CH_TRANSFER_TYPE_SINGLE_BLOCK, + .src_handshaking = (uint32_t)XMC_DMA_CH_SRC_HANDSHAKING_HARDWARE, + .src_peripheral_request = DMA_PERIPHERAL_REQUEST(2U, 11U), /*DMA0_PERIPHERAL_REQUEST_USIC0_SR1_2*/ +}; + +const UART_DMA_CONFIG_t UART_0_rx_dma_config = +{ + .dma_ch_config = &UART_0_rx_dma_ch_config, + .dma_channel = 4U +}; + /*UART APP configuration structure*/ const UART_CONFIG_t UART_0_config = { .channel_config = &UART_0_channel_config, - + .global_dma = &GLOBAL_DMA_0, + .transmit_dma_config = &UART_0_tx_dma_config, + .receive_dma_config = &UART_0_rx_dma_config, .fptr_uart_config = UART_0_init, .sync_error_cbhandler = NULL, .rx_noise_error_cbhandler = NULL, @@ -116,10 +162,10 @@ const UART_CONFIG_t UART_0_config = .collision_error_cbhandler = NULL, .tx_pin_config = &UART_0_tx_pin, .mode = UART_MODE_FULLDUPLEX, - .transmit_mode = UART_TRANSFER_MODE_DIRECT, - .receive_mode = UART_TRANSFER_MODE_DIRECT, - .tx_fifo_size = XMC_USIC_CH_FIFO_SIZE_16WORDS, - .rx_fifo_size = XMC_USIC_CH_FIFO_SIZE_16WORDS, + .transmit_mode = UART_TRANSFER_MODE_DMA, + .receive_mode = UART_TRANSFER_MODE_DMA, + .tx_fifo_size = XMC_USIC_CH_FIFO_DISABLED, + .rx_fifo_size = XMC_USIC_CH_FIFO_DISABLED, }; /*Runtime handler*/ @@ -150,32 +196,65 @@ const XMC_GPIO_CONFIG_t UART_0_rx_pin_config = { UART_STATUS_t UART_0_init() { UART_STATUS_t status = UART_STATUS_SUCCESS; + status = (UART_STATUS_t)GLOBAL_DMA_Init(&GLOBAL_DMA_0); + XMC_DMA_CH_Init(XMC_DMA0, 5U, &UART_0_tx_dma_ch_config); + XMC_DMA_CH_EnableEvent(XMC_DMA0, 5U, XMC_DMA_CH_EVENT_TRANSFER_COMPLETE); + + XMC_DMA_CH_Init(XMC_DMA0, 4U, &UART_0_rx_dma_ch_config); + XMC_DMA_CH_EnableEvent(XMC_DMA0, 4U, XMC_DMA_CH_EVENT_TRANSFER_COMPLETE); + /*Configure Receive pin*/ XMC_GPIO_Init((XMC_GPIO_PORT_t *)PORT1_BASE, 4U, &UART_0_rx_pin_config); /* Initialize USIC channel in UART mode*/ XMC_UART_CH_Init(XMC_UART0_CH0, &UART_0_channel_config); /*Set input source path*/ XMC_USIC_CH_SetInputSource(XMC_UART0_CH0, XMC_USIC_CH_INPUT_DX0, 1U); - /*Configure transmit FIFO*/ - XMC_USIC_CH_TXFIFO_Configure(XMC_UART0_CH0, - 16U, - XMC_USIC_CH_FIFO_SIZE_16WORDS, - 1U); - /*Configure receive FIFO*/ - XMC_USIC_CH_RXFIFO_Configure(XMC_UART0_CH0, - 0U, - XMC_USIC_CH_FIFO_SIZE_16WORDS, - 15U); /* Start UART */ XMC_UART_CH_Start(XMC_UART0_CH0); /* Initialize UART TX pin */ XMC_GPIO_Init((XMC_GPIO_PORT_t *)PORT1_BASE, 5U, &UART_0_tx_pin_config); + /*Set service request for transmit interrupt*/ + XMC_USIC_CH_SetInterruptNodePointer(XMC_UART0_CH0, XMC_USIC_CH_INTERRUPT_NODE_POINTER_TRANSMIT_BUFFER, + 0U); + /*Set service request for receive interrupt*/ + XMC_USIC_CH_SetInterruptNodePointer(XMC_UART0_CH0, XMC_USIC_CH_INTERRUPT_NODE_POINTER_RECEIVE, + 1U); + XMC_USIC_CH_SetInterruptNodePointer(XMC_UART0_CH0, XMC_USIC_CH_INTERRUPT_NODE_POINTER_ALTERNATE_RECEIVE, + 1U); /*Set service request for UART protocol events*/ XMC_USIC_CH_SetInterruptNodePointer(XMC_UART0_CH0, XMC_USIC_CH_INTERRUPT_NODE_POINTER_PROTOCOL, - 0U); + 2U); + /*Register transfer complete event handler*/ + XMC_DMA_CH_SetEventHandler(XMC_DMA0, 4U, UART_0_dma_rx_handler); + /*Register transfer complete event handler*/ + XMC_DMA_CH_SetEventHandler(XMC_DMA0, 5U, UART_0_dma_tx_handler); + /* make DMA ready for transmission*/ + XMC_USIC_CH_TriggerServiceRequest(XMC_UART0_CH0, 0U); return status; } + +void UART_0_dma_tx_handler(XMC_DMA_CH_EVENT_t event) +{ + if(event == XMC_DMA_CH_EVENT_TRANSFER_COMPLETE) + { + UART_0.runtime->tx_busy = false; + elua_uart_tx_callback(); + + } +} + + +void UART_0_dma_rx_handler(XMC_DMA_CH_EVENT_t event) +{ + if(event == XMC_DMA_CH_EVENT_TRANSFER_COMPLETE) + { + UART_0.runtime->rx_busy = false; + elua_uart_rx_callback(); + + } +} + /*CODE_BLOCK_END*/ diff --git a/src/platform/xmc4000/xmclib/gen/UART/uart_conf.h b/src/platform/xmc4000/xmclib/gen/UART/uart_conf.h index 7be8755a..f51735b6 100644 --- a/src/platform/xmc4000/xmclib/gen/UART/uart_conf.h +++ b/src/platform/xmc4000/xmclib/gen/UART/uart_conf.h @@ -61,8 +61,8 @@ #define UART_PATCH_VERSION (10U) -#define UART_TX_DIRECT_USED -#define UART_RX_DIRECT_USED +#define UART_TX_DMA_USED +#define UART_RX_DMA_USED #endif /* End of UART_CONF_H */ /*CODE_BLOCK_END*/ diff --git a/src/platform/xmc4000/xmclib/gen/UART/uart_extern.h b/src/platform/xmc4000/xmclib/gen/UART/uart_extern.h index 942c2413..9d05625c 100644 --- a/src/platform/xmc4000/xmclib/gen/UART/uart_extern.h +++ b/src/platform/xmc4000/xmclib/gen/UART/uart_extern.h @@ -65,6 +65,8 @@ extern "C" { #endif /*Extern declaration for callback functions and UART APP instance handles*/ + extern void elua_uart_tx_callback(void); + extern void elua_uart_rx_callback(void); extern UART_t UART_0;