mirror of
https://github.com/apache/nuttx.git
synced 2026-09-10 02:46:33 +00:00
boards/samv7/common: add support for UART RX DMA polling
This adds the support for RX DMA polling. The board initializes timer channel SAMV7_UART_RXDMA_POLL_TIMER with frequency SAMV7_UART_RXDMA_POLL_FREQUENCY that triggers DMA polling function. Signed-off-by: Michal Lenc <michallenc@seznam.cz>
This commit is contained in:
parent
7af7655234
commit
4fa5e294ac
4 changed files with 339 additions and 0 deletions
|
|
@ -62,6 +62,37 @@ config SAMV7_HSMCI0_MOUNT_MOUNTPOINT
|
|||
|
||||
endif # SAMV7_HSMCI0_MOUNT
|
||||
|
||||
config SAMV7_UART_RXDMA_POLL
|
||||
bool "Enable U(S)ART RX DMA Polling"
|
||||
default n
|
||||
depends on UART0_RXDMA || UART1_RXDMA || UART2_RXDMA || UART3_RXDMA || \
|
||||
UART4_RXDMA || USART0_RXDMA || USART1_RXDMA || USART2_RXDMA
|
||||
---help---
|
||||
UART peripheral with RX DMA need periodic polling that checks the received
|
||||
DMA buffers for received bytes that have not accumulated to the point
|
||||
where the DMA interrupt has triggered.
|
||||
|
||||
if SAMV7_UART_RXDMA_POLL
|
||||
|
||||
config SAMV7_UART_RXDMA_POLL_TIMER
|
||||
int "Timer channel to trigger polling"
|
||||
default 0
|
||||
range 0 11
|
||||
---help---
|
||||
The number of timer channel to trigger the polling. Values from 0 to 11
|
||||
are available. Be careful not to assign the same channel that is
|
||||
already configured to other peripheral (ADC trigger for example).
|
||||
|
||||
config SAMV7_UART_RXDMA_POLL_FREQUENCY
|
||||
int "Timer frequency"
|
||||
default 1000
|
||||
---help---
|
||||
Frequency of the timer to trigger the polling. You might want to keep
|
||||
this reasonably low to avoid unnecessary overhead and negate
|
||||
DMA benefit.
|
||||
|
||||
endif # SAMV7_UART_RXDMA_POLL
|
||||
|
||||
config SAMV7_PROGMEM_OTA_PARTITION
|
||||
bool
|
||||
default n
|
||||
|
|
|
|||
110
boards/arm/samv7/common/include/board_uart_rxdma_poll.h
Normal file
110
boards/arm/samv7/common/include/board_uart_rxdma_poll.h
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/****************************************************************************
|
||||
* boards/arm/samv7/common/include/board_uart_rxdma_poll.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __BOARDS_ARM_SAMV7_COMMON_INCLUDE_BOARD_UART_RXDMA_POLL_H
|
||||
#define __BOARDS_ARM_SAMV7_COMMON_INCLUDE_BOARD_UART_RXDMA_POLL_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_uart_rxdma_poll_stop
|
||||
*
|
||||
* Description:
|
||||
* This function starts the timer polling UART.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void board_uart_rxdma_poll_start(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_uart_rxdma_poll_stop
|
||||
*
|
||||
* Description:
|
||||
* This function stops the timer polling UART. No resourses are freed,
|
||||
* time is just stopped and can be started again.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void board_uart_rxdma_poll_stop(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_uart_rxdma_poll_init
|
||||
*
|
||||
* Description:
|
||||
* This function initializes and starts the timer that is polling
|
||||
* UART/USART peripherals with RX DMA enabled.
|
||||
*
|
||||
* Input Parameters:
|
||||
* channel - Channel number (0-11, see TC_CHANx)
|
||||
* frequency - Timer frequency
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, negative value (errno) on ERROR.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int board_uart_rxdma_poll_init(int channel, uint32_t frequency);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __BOARDS_ARM_SAMV7_COMMON_INCLUDE_BOARD_UART_RXDMA_POLL_H */
|
||||
|
|
@ -46,6 +46,10 @@ ifeq ($(CONFIG_SAMV7_GPIO_ENC),y)
|
|||
CSRCS += sam_gpio_enc.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SAMV7_UART_RXDMA_POLL),y)
|
||||
CSRCS += sam_uart_rxdma_poll.c
|
||||
endif
|
||||
|
||||
DEPPATH += --dep-path src
|
||||
VPATH += :src
|
||||
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src
|
||||
|
|
|
|||
194
boards/arm/samv7/common/src/sam_uart_rxdma_poll.c
Normal file
194
boards/arm/samv7/common/src/sam_uart_rxdma_poll.c
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
/****************************************************************************
|
||||
* boards/arm/samv7/common/src/sam_uart_rxdma_poll.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "sam_tc.h"
|
||||
#include "sam_serial.h"
|
||||
|
||||
#include "board_uart_rxdma_poll.h"
|
||||
|
||||
#ifdef CONFIG_SAMV7_UART_RXDMA_POLL
|
||||
|
||||
static TC_HANDLE poll_tc;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: timer_handler
|
||||
*
|
||||
* Description:
|
||||
* Timer interrupt callback.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tch - The handle that represents the timer state
|
||||
* arg - An opaque argument provided when the interrupt was registered
|
||||
* sr - The value of the timer interrupt status register at the time
|
||||
* that the interrupt occurred.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void timer_handler(TC_HANDLE tch, void *arg, uint32_t sr)
|
||||
{
|
||||
sam_serial_dma_poll();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_uart_rxdma_poll_stop
|
||||
*
|
||||
* Description:
|
||||
* This function starts the timer polling UART.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void board_uart_rxdma_poll_start(void)
|
||||
{
|
||||
sam_tc_start(poll_tc);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_uart_rxdma_poll_stop
|
||||
*
|
||||
* Description:
|
||||
* This function stops the timer polling UART. No resourses are freed,
|
||||
* time is just stopped and can be started again.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void board_uart_rxdma_poll_stop(void)
|
||||
{
|
||||
sam_tc_stop(poll_tc);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_uart_rxdma_poll_init
|
||||
*
|
||||
* Description:
|
||||
* This function initializes and starts the timer that is polling
|
||||
* UART/USART peripherals with RX DMA enabled.
|
||||
*
|
||||
* Input Parameters:
|
||||
* channel - Channel number (0-11, see TC_CHANx)
|
||||
* frequency - Timer frequency
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, negative value (errno) on ERROR.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int board_uart_rxdma_poll_init(int channel, uint32_t frequency)
|
||||
{
|
||||
int ret;
|
||||
uint32_t div;
|
||||
uint32_t tcclks;
|
||||
uint32_t actual;
|
||||
uint32_t mode;
|
||||
uint32_t fdiv;
|
||||
uint32_t regval;
|
||||
|
||||
if (channel < TC_CHAN0 || channel > TC_CHAN11)
|
||||
{
|
||||
syslog(LOG_ERR, "Invalid channel number: %d", channel);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = sam_tc_clockselect(frequency, &tcclks, &actual);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "sam_tc_divisor failed: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
div = BOARD_MCK_FREQUENCY / actual;
|
||||
|
||||
/* Set the timer/counter waveform mode the clock input selected by
|
||||
* sam_tc_clockselect()
|
||||
*/
|
||||
|
||||
mode = ((tcclks << TC_CMR_TCCLKS_SHIFT) | /* Use selected TCCLKS value */
|
||||
TC_CMR_WAVSEL_UPRC | /* UP mode w/ trigger on RC Compare */
|
||||
TC_CMR_WAVE); /* Wave mode */
|
||||
|
||||
/* Now allocate and configure the channel */
|
||||
|
||||
poll_tc = sam_tc_allocate(channel, mode);
|
||||
if (!poll_tc)
|
||||
{
|
||||
syslog(LOG_ERR, "Failed to allocate channel %d mode %08" PRIx32 "\n",
|
||||
channel, mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* The divider returned by sam_tc_clockselect() is the reload value
|
||||
* that will achieve a 1Hz rate. We need to multiply this to get the
|
||||
* desired frequency. sam_tc_divisor() should have already assure
|
||||
* that we can do this without overflowing a 32-bit unsigned integer.
|
||||
*/
|
||||
|
||||
fdiv = div * frequency;
|
||||
DEBUGASSERT(div > 0 && div <= fdiv); /* Will check for integer overflow */
|
||||
|
||||
/* Calculate the actual counter value from this divider and the tc input
|
||||
* frequency.
|
||||
*/
|
||||
|
||||
regval = BOARD_MCK_FREQUENCY / fdiv;
|
||||
sam_tc_setregister(poll_tc, TC_REGC, regval);
|
||||
sam_tc_attach(poll_tc, timer_handler, NULL, TC_INT_CPCS);
|
||||
|
||||
/* And start the timer */
|
||||
|
||||
sam_tc_start(poll_tc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SAMV7_UART_RXDMA_POLL */
|
||||
Loading…
Add table
Add a link
Reference in a new issue