XMC4xxx: Complete lowputc logic

This commit is contained in:
Gregory Nutt 2017-03-20 11:21:32 -06:00
parent ef863598d5
commit 8a3422f837
6 changed files with 383 additions and 183 deletions

View File

@ -515,15 +515,16 @@
*/
#define USIC_DXCR_DSEL_SHIFT (0) /* Bits 0-2: Data Selection for Input Signal */
#define USIC_DXCR_DSEL_MASK (7 << USIC_DX0CR_DSEL_SHIFT)
# define USIC_DXCR_DSEL_DXA (0 << USIC_DX0CR_DSEL_SHIFT) /* Data input DXnA selected */
# define USIC_DXCR_DSEL_DXB (1 << USIC_DX0CR_DSEL_SHIFT) /* Data input DXnB selected */
# define USIC_DXCR_DSEL_DXC (2 << USIC_DX0CR_DSEL_SHIFT) /* Data input DXnC selected */
# define USIC_DXCR_DSEL_DXD (3 << USIC_DX0CR_DSEL_SHIFT) /* Data input DXnD selected */
# define USIC_DXCR_DSEL_DXE (4 << USIC_DX0CR_DSEL_SHIFT) /* Data input DXnE selected */
# define USIC_DXCR_DSEL_DXF (5 << USIC_DX0CR_DSEL_SHIFT) /* Data input DXnF selected */
# define USIC_DXCR_DSEL_DXG (6 << USIC_DX0CR_DSEL_SHIFT) /* Data input DXnG selected */
# define USIC_DXCR_DSEL_ONE (7 << USIC_DX0CR_DSEL_SHIFT) /* Data input is always 1 */
#define USIC_DXCR_DSEL_MASK (7 << USIC_DXCR_DSEL_SHIFT)
# define USIC_DXCR_DSEL_DX(m) ((uint32_t)(m) << USIC_DXCR_DSEL_SHIFT) /* Data input DXnm selected */
# define USIC_DXCR_DSEL_DXA (0 << USIC_DXCR_DSEL_SHIFT) /* Data input DXnA selected */
# define USIC_DXCR_DSEL_DXB (1 << USIC_DXCR_DSEL_SHIFT) /* Data input DXnB selected */
# define USIC_DXCR_DSEL_DXC (2 << USIC_DXCR_DSEL_SHIFT) /* Data input DXnC selected */
# define USIC_DXCR_DSEL_DXD (3 << USIC_DXCR_DSEL_SHIFT) /* Data input DXnD selected */
# define USIC_DXCR_DSEL_DXE (4 << USIC_DXCR_DSEL_SHIFT) /* Data input DXnE selected */
# define USIC_DXCR_DSEL_DXF (5 << USIC_DXCR_DSEL_SHIFT) /* Data input DXnF selected */
# define USIC_DXCR_DSEL_DXG (6 << USIC_DXCR_DSEL_SHIFT) /* Data input DXnG selected */
# define USIC_DXCR_DSEL_ONE (7 << USIC_DXCR_DSEL_SHIFT) /* Data input is always 1 */
#define USIC_DX1CR_DCEN (1 << 3) /* Bit 3: Delay Compensation Enable (DX1CR only) */
#define USIC_DXCR_INSW (1 << 4) /* Bit 4: Input Switch */
#define USIC_DXCR_DFEN (1 << 5) /* Bit 5: Digital Filter Enable */
@ -531,17 +532,19 @@
#define USIC_DXCR_DPOL (1 << 8) /* Bit 8: Data Polarity for DXn */
#define USIC_DXCR_SFSEL (1 << 9) /* Bit 9: Sampling Frequency Selection */
#define USIC_DXCR_CM_SHIFT (10) /* Bits 10-11: Combination Mode */
#define USIC_DXCR_CM_MASK (3 << USIC_DX0CR_CM_SHIFT)
# define USIC_DXCR_CM_DISABLE (0 << USIC_DX0CR_CM_SHIFT) /* Trigger activation disabled */
# define USIC_DXCR_CM_RISING (1 << USIC_DX0CR_CM_SHIFT) /* Rising edge activates DXnT */
# define USIC_DXCR_CM_FALLING (2 << USIC_DX0CR_CM_SHIFT) /* Falling edge activates DXnT */
# define USIC_DXCR_CM_BOTH (3 << USIC_DX0CR_CM_SHIFT) /* Both edges activate DXnT */
#define USIC_DXCR_CM_MASK (3 << USIC_DXCR_CM_SHIFT)
# define USIC_DXCR_CM_DISABLE (0 << USIC_DXCR_CM_SHIFT) /* Trigger activation disabled */
# define USIC_DXCR_CM_RISING (1 << USIC_DXCR_CM_SHIFT) /* Rising edge activates DXnT */
# define USIC_DXCR_CM_FALLING (2 << USIC_DXCR_CM_SHIFT) /* Falling edge activates DXnT */
# define USIC_DXCR_CM_BOTH (3 << USIC_DXCR_CM_SHIFT) /* Both edges activate DXnT */
#define USIC_DXCR_DXS (1 << 15) /* Bit 15: Synchronized Data Value */
/* Shift Control Register */
#define USIC_SCTR_SDIR (1 << 0) /* Bit 0: Shift Direction */
#define USIC_SCTR_PDL (1 << 1) /* Bit 1: Passive Data Level */
# define USIC_SCTR_PDL0 (0) /* 0=Passive data level is 0 */
# define USIC_SCTR_PDL1 (1 << 1) /* 1=Passive data level is 1 */
#define USIC_SCTR_DSM_SHIFT (2) /* Bits 2-3: Data Shift Mode */
#define USIC_SCTR_DSM_MASK (3 << USIC_SCTR_DSM_SHIFT)
# define USIC_SCTR_DSM_1BIT (0 << USIC_SCTR_DSM_SHIFT) /* Data is shifted one bit at a time */
@ -555,8 +558,8 @@
#define USIC_SCTR_TRM_SHIFT (8) /* Bits 8-9: Transmission Mode */
#define USIC_SCTR_TRM_MASK (3 << USIC_SCTR_TRM_SHIFT)
# define USIC_SCTR_TRM_INACTIVE (0 << USIC_SCTR_TRM_SHIFT) /* Inactive */
# define USIC_SCTR_TRM_0LEVEL (1 << USIC_SCTR_TRM_SHIFT) /* Active at 1-level */
# define USIC_SCTR_TRM_1LEVEL (2 << USIC_SCTR_TRM_SHIFT) /* Active if it is at 0-level */
# define USIC_SCTR_TRM_1LEVEL (1 << USIC_SCTR_TRM_SHIFT) /* Active at 1-level */
# define USIC_SCTR_TRM_0LEVEL (2 << USIC_SCTR_TRM_SHIFT) /* Active at 0-level */
# define USIC_SCTR_TRM_ACTIVE (3 << USIC_SCTR_TRM_SHIFT) /* Active without regard to signal level */
#define USIC_SCTR_FLE_SHIFT (16) /* Bits 16-21: Frame Length */
#define USIC_SCTR_FLE_MASK (0x3f << USIC_SCTR_FLE_SHIFT)
@ -638,7 +641,8 @@
# define USIC_PCR_ASCMODE_SP(n) ((uint32_t)(n) << USIC_PCR_ASCMODE_SP_SHIFT)
#define USIC_PCR_ASCMODE_PL_SHIFT (13) /* Bits 13-15: Pulse Length */
#define USIC_PCR_ASCMODE_PL_MASK (7 << USIC_PCR_ASCMODE_PL_SHIFT)
#define USIC_PCR_ASCMODE_PL(n) ((uint32_t)((n)-1) << USIC_PCR_ASCMODE_PL_SHIFT)
#define USIC_PCR_ASCMODE_PLBIT (0 << USIC_PCR_ASCMODE_PL_SHIFT) /* Pulse length = bit length */
#define USIC_PCR_ASCMODE_PL(n) ((uint32_t)((n)-1) << USIC_PCR_ASCMODE_PL_SHIFT) /* Pulse length = n quanta */
#define USIC_PCR_ASCMODE_RSTEN (1 << 16) /* Bit 16: Receiver Status Enable */
#define USIC_PCR_ASCMODE_TSTEN (1 << 17) /* Bit 17: Transmitter Status Enable */
#define USIC_PCR_ASCMODE_MCLK (1 << 31) /* Bit 31: Master Clock Enable */
@ -717,7 +721,7 @@
# define USIC_CCR_HPCEN_DX0_2 (3 << USIC_CCR_HPCEN_SHIFT) /* Port control enabled for DX0, DX[5:3] and DOUT[3:0] */
#define USIC_CCR_PM_SHIFT (8) /* Bits 8-9: Parity Mode */
#define USIC_CCR_PM_MASK (3 << USIC_CCR_PM_SHIFT)
# define USIC_CCR_PM_DISABLE (0 << USIC_CCR_PM_SHIFT) /* Parity generation is disabled */
# define USIC_CCR_PM_NONE (0 << USIC_CCR_PM_SHIFT) /* Parity generation is disabled */
# define USIC_CCR_PM_EVEN (2 << USIC_CCR_PM_SHIFT) /* Even parity is selected */
# define USIC_CCR_PM_ODD (3 << USIC_CCR_PM_SHIFT) /* Odd parity is selected */
#define USIC_CCR_RSIEN (1 << 10) /* Bit 10: Receiver Start Interrupt Enable */

View File

@ -52,6 +52,7 @@
#include "chip/xmc4_usic.h"
#include "chip/xmc4_pinmux.h"
#include "xmc4_usic.h"
#include "xmc4_gpio.h"
#include "xmc4_lowputc.h"
/****************************************************************************
@ -64,6 +65,7 @@
# if defined(CONFIG_UART0_SERIAL_CONSOLE)
# define CONSOLE_CHAN USIC0_CHAN0
# define CONSOLE_FREQ BOARD_CORECLK_FREQ
# define CONSOLE_DX BOARD_UART0_DX
# define CONSOLE_BAUD CONFIG_UART0_BAUD
# define CONSOLE_BITS CONFIG_UART0_BITS
# define CONSOLE_2STOP CONFIG_UART0_2STOP
@ -71,6 +73,7 @@
# elif defined(CONFIG_UART1_SERIAL_CONSOLE)
# define CONSOLE_CHAN USIC0_CHAN1
# define CONSOLE_FREQ BOARD_CORECLK_FREQ
# define CONSOLE_DX BOARD_UART1_DX
# define CONSOLE_BAUD CONFIG_UART1_BAUD
# define CONSOLE_BITS CONFIG_UART1_BITS
# define CONSOLE_2STOP CONFIG_UART1_2STOP
@ -78,6 +81,7 @@
# elif defined(CONFIG_UART2_SERIAL_CONSOLE)
# define CONSOLE_CHAN USIC1_CHAN0
# define CONSOLE_FREQ BOARD_BUS_FREQ
# define CONSOLE_DX BOARD_UART2_DX
# define CONSOLE_BAUD CONFIG_UART2_BAUD
# define CONSOLE_BITS CONFIG_UART2_BITS
# define CONSOLE_2STOP CONFIG_UART2_2STOP
@ -85,6 +89,7 @@
# elif defined(CONFIG_UART3_SERIAL_CONSOLE)
# define CONSOLE_CHAN USIC1_CHAN1
# define CONSOLE_FREQ BOARD_BUS_FREQ
# define CONSOLE_DX BOARD_UART3_DX
# define CONSOLE_BAUD CONFIG_UART3_BAUD
# define CONSOLE_BITS CONFIG_UART3_BITS
# define CONSOLE_2STOP CONFIG_UART3_2STOP
@ -92,6 +97,7 @@
# elif defined(CONFIG_UART4_SERIAL_CONSOLE)
# define CONSOLE_CHAN USIC2_CHAN0
# define CONSOLE_FREQ BOARD_BUS_FREQ
# define CONSOLE_DX BOARD_UART4_DX
# define CONSOLE_BAUD CONFIG_UART4_BAUD
# define CONSOLE_BITS CONFIG_UART4_BITS
# define CONSOLE_2STOP CONFIG_UART4_2STOP
@ -99,6 +105,7 @@
# elif defined(CONFIG_UART5_SERIAL_CONSOLE)
# define CONSOLE_CHAN USIC2_CHAN1
# define CONSOLE_FREQ BOARD_BUS_FREQ
# define CONSOLE_DX BOARD_UART5_DX
# define CONSOLE_BAUD CONFIG_UART5_BAUD
# define CONSOLE_BITS CONFIG_UART5_BITS
# define CONSOLE_2STOP CONFIG_UART5_2STOP
@ -108,10 +115,27 @@
# endif
#endif /* HAVE_UART_CONSOLE */
/* REVISIT: Oversampling is hardcoded to 16 here. Perhaps this should be in
* the config structure.
*/
#define UART_OVERSAMPLING 16
/****************************************************************************
* Private Functions
* Private Data
****************************************************************************/
#ifdef HAVE_UART_CONSOLE
static const struct uart_config_s g_console_config =
{
.baud = CONSOLE_BAUD,
.dx = CONSOLE_DX,
.parity = CONSOLE_PARITY,
.nbits = CONSOLE_BITS,
.stop2 = CONSOLE_2STOP
};
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -127,25 +151,26 @@
void up_lowputc(char ch)
{
#ifdef HAVE_UART_CONSOLE
/* Wait until the transmit data register is "empty" (TDRE). This state
* depends on the TX watermark setting and may not mean that the transmit
* buffer is truly empty. It just means that we can now add another
* character to the transmit buffer without exceeding the watermark.
*
* NOTE: UART0 has an 8-byte deep FIFO; the other UARTs have no FIFOs
* (1-deep). There appears to be no way to know when the FIFO is not
* full (other than reading the FIFO length and comparing the FIFO count).
* Hence, the FIFOs are not used in this implementation and, as a result
* TDRE indeed mean that the single output buffer is available.
*
* Performance on UART0 could be improved by enabling the FIFO and by
* redesigning all of the FIFO status logic.
*/
#warning Missing logic
uintptr_t base;
uint32_t regval;
/* Then write the character to the UART data register */
/* Get the base address of the USIC registers associated with this channel */
#warning Missing logic
base = xmc4_channel_baseaddress(CONSOLE_CHAN);
DEBUGASSERT(base != 0);
/* Wait for the transmit buffer/fifo to be "not full." */
do
{
regval = getreg32(base + XMC4_USIC_TRBSR_OFFSET);
}
while ((regval & USIC_TRBSR_TFULL) != 0);
/* Then write the character to the USIC IN register */
putreg32((uint32_t)ch, base + XMC4_USIC_IN_OFFSET);
#endif
}
/****************************************************************************
@ -160,40 +185,55 @@ void up_lowputc(char ch)
void xmc4_lowsetup(void)
{
uint32_t regval;
#ifdef HAVE_UART_DEVICE
/* Configure UART pins for the all enabled UARTs.
*
* NOTE that the board must provide the definitions in the board.h header
* file of the form like: GPIO_UARTn_RXm and GPIO_UARTn_TXm where n is
* the USIC module, 0..(XMC_NUSIC-1), and m is the USIC channel number, 0
* or 1.
*
* In additional, the board.h must provide the definition of
* BOARD_BOARD_UARTn_DX which indicates which input pin is selected, i.e.
* one of the 0=DXA, 1=DXB, ... 6=DXG.
*/
/* Enable peripheral clocking for all enabled UARTs. */
#warning Missing logic
/* Configure UART pins for the all enabled UARTs */
#ifdef HAVE_UART0
(void)xmc4_gpio_config(GPIO_UART0_RXD0);
(void)xmc4_gpio_config(GPIO_UART0_TXD0);
#endif
#ifdef HAVE_UART1
(void)xmc4_gpio_config(GPIO_UART0_RXD1);
(void)xmc4_gpio_config(GPIO_UART0_TXD1);
#endif
#ifdef HAVE_UART2
(void)xmc4_gpio_config(GPIO_UART0_RXD2);
(void)xmc4_gpio_config(GPIO_UART0_TXD2);
#endif
#ifdef HAVE_UART3
(void)xmc4_gpio_config(GPIO_UART0_RXD3);
(void)xmc4_gpio_config(GPIO_UART0_TXD3);
#endif
#ifdef HAVE_UART4
(void)xmc4_gpio_config(GPIO_UART0_RXD4);
(void)xmc4_gpio_config(GPIO_UART0_TXD4);
#endif
#ifdef HAVE_UART5
(void)xmc4_gpio_config(GPIO_UART0_RXD5);
(void)xmc4_gpio_config(GPIO_UART0_TXD5);
#endif
#ifdef HAVE_UART_CONSOLE
/* Configure the console (only) now. Other UARTs will be configured
* when the serial driver is opened.
*/
xmc4_uart_configure(CONSOLE_CHAN, CONSOLE_BAUD, CONSOLE_FREQ, \
CONSOLE_PARITY, CONSOLE_BITS, CONSOLE_2STOP);
xmc4_uart_configure(CONSOLE_CHAN, &g_console_config);
#endif /* HAVE_UART_CONSOLE */
#endif /* HAVE_UART_DEVICE */
}
/****************************************************************************
* Name: xmc4_uart_reset
*
* Description:
* Reset a UART.
*
****************************************************************************/
#ifdef HAVE_UART_DEVICE
void xmc4_uart_reset(uintptr_t uart_base)
{
uint8_t regval;
/* Just disable the transmitter and receiver */
#warning Missing logic
}
#endif
/****************************************************************************
* Name: xmc4_uart_configure
*
@ -207,12 +247,11 @@ void xmc4_uart_reset(uintptr_t uart_base)
****************************************************************************/
#ifdef HAVE_UART_DEVICE
int xmc4_uart_configure(enum usic_channel_e channel, uint32_t baud,
uint32_t clock, unsigned int parity,
unsigned int nbits, unsigned int stop2)
int xmc4_uart_configure(enum usic_channel_e channel,
FAR const struct uart_config_s *config)
{
uintptr_t base;
uint32_t oversampling;
uint32_t regval;
int ret;
/* Get the base address of the USIC registers associated with this channel */
@ -231,30 +270,159 @@ int xmc4_uart_configure(enum usic_channel_e channel, uint32_t baud,
return ret;
}
ret = xmc4_uisc_baudrate(channel, baud, oversampling);
/* Configure the BAUD rate.
* REVISIT: Oversample is hardcoded to 16 here. Perhaps this should be in
* the config structure.
*/
/* Configure number of bits, stop bits and parity */
#warning Missing logic
ret = xmc4_uisc_baudrate(channel, config->baud, UART_OVERSAMPLING);
/* Check for odd parity */
#warning Missing logic
/* Configure frame format.
*
* - Pulse length for standard UART signaling, i.e. the 0 level is
* signaled during the complete bit time
* - Enable Sample Majority Decision sample mode
*/
/* Check for even parity */
#warning Missing logic
regval = USIC_PCR_ASCMODE_PLBIT | USIC_PCR_ASCMODE_SMD;
/* Check for 9-bit operation */
#warning Missing logic
/* - Sampling point set equal to the half of the oversampling period */
/* Calculate baud settings (truncating) */
#warning Missing logic
regval |= USIC_PCR_ASCMODE_SP((UART_OVERSAMPLING >> 1) + 1);
/* Configure FIFOs */
#warning Missing logic
/* - Configure the number of stop bits */
/* Enable RX and TX FIFOs */
#warning Missing logic
if (config->stop2)
{
regval |= USIC_PCR_ASCMODE_STPB;
}
/* Now we can (re-)enable the transmitter and receiver */
#warning Missing logic
putreg32(regval, base + XMC4_USIC_PCR_OFFSET);
/* Configure Shift Control Register:
*
* - Set passive data level, high
* - Transmission Mode: The shift control signal is considered active if
* it is at 1-level. This is the setting to be programmed to allow
* data transfers.
* - Set word length
* - Set frame length equal to the word length
*/
regval = USIC_SCTR_PDL0 | USIC_SCTR_TRM_1LEVEL |
USIC_SCTR_FLE(config->nbits) | USIC_SCTR_WLE(config->nbits);
putreg32(regval, base + XMC4_USIC_SCTR_OFFSET);
/* Enable transfer buffer */
regval = USIC_TCSR_TDEN_TDIV | USIC_TCSR_TDSSM;
putreg32(regval, base + XMC4_USIC_TCSR_OFFSET);
/* Clear protocol status */
putreg32(0xffffffff, base + XMC4_USIC_PSCR_OFFSET);
/* Configure parity */
if (config->parity == 1)
{
/* Odd parrity */
regval = USIC_CCR_PM_ODD;
}
else if (config->parity == 2)
{
/* Even parity */
regval = USIC_CCR_PM_EVEN;
}
else
{
/* No parity */
DEBUGASSERT(config->parity == 0);
regval = USIC_CCR_PM_NONE;
}
putreg32(regval, base + XMC4_USIC_CCR_OFFSET);
/* Set DX0CR input source path */
regval = getreg32(base + XMC4_USIC_DX0CR_OFFSET);
regval &= ~USIC_DXCR_DSEL_MASK;
regval |= USIC_DXCR_DSEL_DX(config->dx);
putreg32(regval, base + XMC4_USIC_DX0CR_OFFSET);
/* Disable transmit FIFO */
regval = getreg32(base + XMC4_USIC_TBCTR_OFFSET);
regval &= ~USIC_TBCTR_SIZE_MASK;
putreg32(regval, base + XMC4_USIC_TBCTR_OFFSET);
/* Configure transmit FIFO
*
* - DPTR = 16
* - LIMIT = 1
* - STBTEN = 0, the trigger of the standard transmit buffer event is
* based on the transition of the fill level from equal to below the
* limit, not the fact being below
* - SIZE = 16
* - LOF = 0, A standard transmit buffer event occurs when the filling
* level equals the limit value and gets lower due to transmission of
* a data word
*/
regval &= ~(USIC_TBCTR_DPTR_MASK | USIC_TBCTR_LIMIT_MASK | USIC_RBCTR_SRBTEN |
USIC_TBCTR_SIZE_MASK | USIC_RBCTR_LOF);
regval |= (USIC_TBCTR_DPTR(16) | USIC_TBCTR_LIMIT(1) | USIC_TBCTR_SIZE_16);
putreg32(regval, base + XMC4_USIC_TBCTR_OFFSET);
/* Disable the receive FIFO */
regval = getreg32(base + XMC4_USIC_RBCTR_OFFSET);
regval &= ~USIC_RBCTR_SIZE_MASK;
putreg32(regval, base + XMC4_USIC_RBCTR_OFFSET);
/* Configure receive FIFO.
*
* - DPTR = 0
* - LIMIT = 15
* - SIZE = 16
* - LOF = 1, A standard receive buffer event occurs when the filling
* level equals the limit value and gets bigger due to the reception
* of a new data word
*/
regval &= ~(USIC_RBCTR_DPTR_MASK | USIC_RBCTR_LIMIT_MASK | USIC_RBCTR_SIZE_MASK);
regval |= (USIC_RBCTR_DPTR(0) | USIC_RBCTR_LIMIT(15) | USIC_RBCTR_SIZE_16 | USIC_RBCTR_LOF);
putreg32(regval, base + XMC4_USIC_RBCTR_OFFSET);
/* Start UART */
regval = getreg32(base + XMC4_USIC_CCR_OFFSET);
regval &= ~USIC_CCR_MODE_MASK;
regval |= USIC_CCR_MODE_ASC;
putreg32(regval, base + XMC4_USIC_CCR_OFFSET);
/* Set service request for UART protocol events.
*
* Set channel 0 protocol events on sevice request 0
* Set channel 1 protocol events on sevice request 1
*/
regval = getreg32(base + XMC4_USIC_INPR_OFFSET);
regval &= ~USIC_INPR_PINP_MASK;
if (((unsigned int)channel & 1) != 0)
{
regval |= USIC_INPR_PINP_SR0;
}
else
{
regval |= USIC_INPR_PINP_SR1;
}
putreg32(regval, base + XMC4_USIC_INPR_OFFSET);
return OK;
}
#endif

View File

@ -47,6 +47,21 @@
#include "xmc4_config.h"
#include "xmc4_usic.h"
/****************************************************************************
* Public Types
****************************************************************************/
/* This structure provides the configuration of one UART channel */
struct uart_config_s
{
uint32_t baud; /* Desired BAUD rate */
uint8_t dx; /* Input pin 0=DXA, 1=DXB, ... 6=DXG */
uint8_t parity; /* Parity selection: 0=none, 1=odd, 2=even */
uint8_t nbits; /* Number of bits per word */
bool stop2; /* true=2 stop bits; false=1 stop bit */
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
@ -63,18 +78,6 @@
void xmc4_lowsetup(void);
/****************************************************************************
* Name: xmc4_uart_reset
*
* Description:
* Reset a UART.
*
****************************************************************************/
#ifdef HAVE_UART_DEVICE
void xmc4_uart_reset(uintptr_t uart_base);
#endif
/****************************************************************************
* Name: xmc4_uart_configure
*
@ -88,9 +91,8 @@ void xmc4_uart_reset(uintptr_t uart_base);
****************************************************************************/
#ifdef HAVE_UART_DEVICE
int xmc4_uart_configure(enum usic_channel_e channel, uint32_t baud,
uint32_t clock, unsigned int parity,
unsigned int nbits, unsigned int stop2);
int xmc4_uart_configure(enum usic_channel_e channel,
FAR const struct uart_config_s *config);
#endif
/****************************************************************************

View File

@ -227,17 +227,18 @@
* Private Types
****************************************************************************/
/* This structure provides the state of one UART device */
struct xmc4_dev_s
{
uintptr_t uartbase; /* Base address of UART registers */
uint32_t baud; /* Configured baud */
uint32_t clock; /* Clocking frequency of the UART module */
uint8_t channel; /* USIC channel identification */
uint8_t irqs; /* Status IRQ associated with this UART (for enable) */
uint8_t ie; /* Interrupts enabled */
uint8_t parity; /* 0=none, 1=odd, 2=even */
uint8_t bits; /* Number of bits (8 or 9) */
uint8_t stop2; /* Use 2 stop bits */
/* UART configuration */
struct uart_config_s config;
};
/****************************************************************************
@ -314,13 +315,16 @@ static char g_uart5txbuffer[CONFIG_UART5_TXBUFSIZE];
static struct xmc4_dev_s g_uart0priv =
{
.uartbase = XMC4_USIC0_CH0_BASE,
.clock = BOARD_CORECLK_FREQ,
.channel = (uint8_t)USIC0_CHAN0,
.baud = CONFIG_UART0_BAUD,
.irqs = XMC4_IRQ_USIC0,
.parity = CONFIG_UART0_PARITY,
.bits = CONFIG_UART0_BITS,
.stop2 = CONFIG_UART0_2STOP,
.irqs = XMC4_IRQ_USIC0_SR0,
.config =
{
.baud = CONFIG_UART0_BAUD,
.dx = BOARD_UART0_DX,
.parity = CONFIG_UART0_PARITY,
.nbits = CONFIG_UART0_BITS,
.stop2 = CONFIG_UART0_2STOP,
}
};
static uart_dev_t g_uart0port =
@ -346,13 +350,16 @@ static uart_dev_t g_uart0port =
static struct xmc4_dev_s g_uart1priv =
{
.uartbase = XMC4_USIC0_CH1_BASE,
.clock = BOARD_CORECLK_FREQ,
.channel = (uint8_t)USIC0_CHAN1,
.baud = CONFIG_UART1_BAUD,
.irqs = XMC4_IRQ_USIC1,
.parity = CONFIG_UART1_PARITY,
.bits = CONFIG_UART1_BITS,
.stop2 = CONFIG_UART1_2STOP,
.irqs = XMC4_IRQ_USIC0_SR1,
.config =
{
.baud = CONFIG_UART1_BAUD,
.dx = BOARD_UART1_DX,
.parity = CONFIG_UART1_PARITY,
.nbits = CONFIG_UART1_BITS,
.stop2 = CONFIG_UART1_2STOP,
}
};
static uart_dev_t g_uart1port =
@ -378,13 +385,16 @@ static uart_dev_t g_uart1port =
static struct xmc4_dev_s g_uart2priv =
{
.uartbase = XMC4_USIC1_CH0_BASE,
.clock = BOARD_BUS_FREQ,
.channel = (uint8_t)USIC1_CHAN0,
.baud = CONFIG_UART2_BAUD,
.irqs = XMC4_IRQ_USIC2,
.parity = CONFIG_UART2_PARITY,
.bits = CONFIG_UART2_BITS,
.stop2 = CONFIG_UART2_2STOP,
.irqs = XMC4_IRQ_USIC1_SR0,
.config =
{
.baud = CONFIG_UART2_BAUD,
.dx = BOARD_UART2_DX,
.parity = CONFIG_UART2_PARITY,
.nbits = CONFIG_UART2_BITS,
.stop2 = CONFIG_UART2_2STOP,
}
};
static uart_dev_t g_uart2port =
@ -410,13 +420,16 @@ static uart_dev_t g_uart2port =
static struct xmc4_dev_s g_uart3priv =
{
.uartbase = XMC4_USIC1_CH1_BASE,
.clock = BOARD_BUS_FREQ,
.channel = (uint8_t)USIC1_CHAN1,
.baud = CONFIG_UART3_BAUD,
.irqs = XMC4_IRQ_USIC3,
.parity = CONFIG_UART3_PARITY,
.bits = CONFIG_UART3_BITS,
.stop2 = CONFIG_UART3_2STOP,
.irqs = XMC4_IRQ_USIC1_SR1,
.config =
{
.baud = CONFIG_UART3_BAUD,
.dx = BOARD_UART3_DX,
.parity = CONFIG_UART3_PARITY,
.nbits = CONFIG_UART3_BITS,
.stop2 = CONFIG_UART3_2STOP,
}
};
static uart_dev_t g_uart3port =
@ -442,13 +455,16 @@ static uart_dev_t g_uart3port =
static struct xmc4_dev_s g_uart4priv =
{
.uartbase = XMC4_USIC2_CH0_BASE,
.clock = BOARD_BUS_FREQ,
.channel = (uint8_t)USIC2_CHAN0,
.baud = CONFIG_UART4_BAUD,
.irqs = XMC4_IRQ_USIC4,
.parity = CONFIG_UART4_PARITY,
.bits = CONFIG_UART4_BITS,
.stop2 = CONFIG_UART4_2STOP,
.irqs = XMC4_IRQ_USIC2_SR0,
.config =
{
.baud = CONFIG_UART4_BAUD,
.dx = BOARD_UART4_DX,
.parity = CONFIG_UART4_PARITY,
.nbits = CONFIG_UART4_BITS,
.stop2 = CONFIG_UART4_2STOP,
}
};
static uart_dev_t g_uart4port =
@ -474,13 +490,16 @@ static uart_dev_t g_uart4port =
static struct xmc4_dev_s g_uart5priv =
{
.uartbase = XMC4_USIC2_CH1_BASE,
.clock = BOARD_BUS_FREQ,
.channel = (uint8_t)USIC2_CHAN1,
.baud = CONFIG_UART5_BAUD,
.irqs = XMC4_IRQ_USIC5,
.parity = CONFIG_UART5_PARITY,
.bits = CONFIG_UART5_BITS,
.stop2 = CONFIG_UART5_2STOP,
.irqs = XMC4_IRQ_USIC2_SR1,
.config =
{
.baud = CONFIG_UART5_BAUD,
.dx = BOARD_UART5_DX,
.parity = CONFIG_UART5_PARITY,
.nbits = CONFIG_UART5_BITS,
.stop2 = CONFIG_UART5_2STOP,
}
};
static uart_dev_t g_uart5port =
@ -508,7 +527,7 @@ static uart_dev_t g_uart5port =
* Name: up_serialin
****************************************************************************/
static inline uint8_t up_serialin(struct xmc4_dev_s *priv, int offset)
static inline uint32_t up_serialin(struct xmc4_dev_s *priv, int offset)
{
return getreg8(priv->uartbase + offset);
}
@ -517,7 +536,7 @@ static inline uint8_t up_serialin(struct xmc4_dev_s *priv, int offset)
* Name: up_serialout
****************************************************************************/
static inline void up_serialout(struct xmc4_dev_s *priv, int offset, uint8_t value)
static inline void up_serialout(struct xmc4_dev_s *priv, int offset, uint32_t value)
{
putreg8(value, priv->uartbase + offset);
}
@ -586,8 +605,7 @@ static int xmc4_setup(struct uart_dev_s *dev)
/* Configure the UART as an RS-232 UART */
xmc4_uart_configure(priv->uartbase, priv->baud, priv->clock,
priv->parity, priv->bits, priv->stop2);
xmc4_uart_configure(priv->uartbase, &priv->config);
#endif
/* Make sure that all interrupts are disabled */
@ -615,7 +633,7 @@ static void xmc4_shutdown(struct uart_dev_s *dev)
/* Reset hardware and disable Rx and Tx */
xmc4_uart_reset(priv->uartbase);
xmc4_uart_disable(priv->channel);
}
/****************************************************************************
@ -807,32 +825,23 @@ static int xmc4_ioctl(struct file *filep, int cmd, unsigned long arg)
static int xmc4_receive(struct uart_dev_s *dev, uint32_t *status)
{
struct xmc4_dev_s *priv = (struct xmc4_dev_s *)dev->priv;
uint8_t s1;
uint32_t outr;
/* Get error status information:
*
* FE: Framing error. To clear FE, read S1 with FE set and then read
* read UART data register (D).
* NF: Noise flag. To clear NF, read S1 and then read the UART data
* register (D).
* PF: Parity error flag. To clear PF, read S1 and then read the UART
* data register (D).
*/
/* Get input data along with receiver control information */
s1 = up_serialin(priv, XMC4_UART_S1_OFFSET);
outr = up_serialin(priv, XMC4_UART_S1_OFFSET);
up_serialout(priv, XMC4_USIC_OUTR_OFFSET, (uint32_t)ch);
/* Return status information */
/* Return receiver control information */
if (status)
{
*status = (uint32_t)s1;
*status = outr >> USIC_OUTR_RCI_SHIFT;
}
/* Then return the actual received byte. Reading S1 then D clears all
* RX errors.
*/
/* Then return the actual received data. */
return (int)up_serialin(priv, XMC4_UART_D_OFFSET);
return outr & USIC_OUTR_DSR_MASK;
}
/****************************************************************************
@ -885,14 +894,12 @@ static void xmc4_rxint(struct uart_dev_s *dev, bool enable)
static bool xmc4_rxavailable(struct uart_dev_s *dev)
{
struct xmc4_dev_s *priv = (struct xmc4_dev_s *)dev->priv;
/* Return true if the receive data register is full (RDRF). NOTE: If
* FIFOS are enabled, this does not mean that the FIFO is full,
* rather, it means that the number of bytes in the RX FIFO has
* exceeded the watermark setting. There may actually be RX data
* available!
*/
uint32_t regval;
return (up_serialin(priv, XMC4_UART_S1_OFFSET) & UART_S1_RDRF) != 0;
/* Return true if the transmit buffer/fifo is not "empty." */
regval = up_serialin(priv, XMC4_UART_TRBSR_OFFSET);
return ((regval & USIC_TRBSR_REMPTY) == 0);
}
/****************************************************************************
@ -906,7 +913,7 @@ static bool xmc4_rxavailable(struct uart_dev_s *dev)
static void xmc4_send(struct uart_dev_s *dev, int ch)
{
struct xmc4_dev_s *priv = (struct xmc4_dev_s *)dev->priv;
up_serialout(priv, XMC4_UART_D_OFFSET, (uint8_t)ch);
up_serialout(priv, XMC4_USIC_IN_OFFSET, (uint32_t)ch);
}
/****************************************************************************
@ -960,15 +967,12 @@ static void xmc4_txint(struct uart_dev_s *dev, bool enable)
static bool xmc4_txready(struct uart_dev_s *dev)
{
struct xmc4_dev_s *priv = (struct xmc4_dev_s *)dev->priv;
uint32_t regval;
/* Return true if the transmit data register is "empty." NOTE: If
* FIFOS are enabled, this does not mean that the FIFO is empty,
* rather, it means that the number of bytes in the TX FIFO is
* below the watermark setting. There may actually be space for
* additional TX data.
*/
/* Return true if the transmit buffer/fifo is "not full." */
return (up_serialin(priv, XMC4_UART_S1_OFFSET) & UART_S1_TDRE) != 0;
regval = up_serialin(priv, XMC4_UART_TRBSR_OFFSET);
return ((regval & USIC_TRBSR_TFULL) == 0);
}
/****************************************************************************
@ -982,10 +986,12 @@ static bool xmc4_txready(struct uart_dev_s *dev)
static bool xmc4_txempty(struct uart_dev_s *dev)
{
struct xmc4_dev_s *priv = (struct xmc4_dev_s *)dev->priv;
uint32_t regval;
/* Return true if the transmit buffer/fifo is "empty." */
return (up_serialin(priv, XMC4_UART_SFIFO_OFFSET) & UART_SFIFO_TXEMPT) != 0;
regval = up_serialin(priv, XMC4_UART_TRBSR_OFFSET);
return ((regval & USIC_TRBSR_TEMPTY) != 0);
}
/****************************************************************************

View File

@ -44,10 +44,6 @@
#include <stdint.h>
#include "xmc4_config.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Types
****************************************************************************/
@ -56,9 +52,9 @@
enum usic_e
{
USIC0 = 0, /* USIC0 */
USIC1 = 1, /* USIC1 */
USIC2 = 2 /* USIC2 */
USIC0 = 0, /* USIC0 */
USIC1 = 1, /* USIC1 */
USIC2 = 2 /* USIC2 */
};
/* This enumeration identifies USIC channels */
@ -73,6 +69,19 @@ enum usic_channel_e
USIC2_CHAN1 = 5 /* USIC2, Channel 1 */
};
/* This enumeration defines values for the dx input selection */
enum uart_dx_e
{
USIC_DXA = 0, /* USICn_DXmA */
USIC_DXB = 1, /* USICn_DXmB */
USIC_DXC = 2, /* USICn_DXmC */
USIC_DXD = 3, /* USICn_DXmD */
USIC_DXE = 4, /* USICn_DXmE */
USIC_DXF = 5, /* USICn_DXmF */
USIC_DXG = 6 /* USICn_DXmG */
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/

View File

@ -192,6 +192,17 @@
#define BUTTON_0_BIT (1 << BUTTON_0)
#define BUTTON_1_BIT (1 << BUTTON_1)
/* USIC0 ****************************************************************************/
/* USIC0 CH0 is used as UART0
*
* RX - P1.4
* TX - P1.5
*/
#define BOARD_UART0_DX USIC_DXB
#define GPIO_UART0_RXD0 GPIO_U0C0_DX0B
#define GPIO_UART0_TXD0 (GPIO_U0C0_DOUT0_3 | GPIO_PADA1P_STRONGSOFT | GPIO_OUTPUT_SET)
/************************************************************************************
* Public Data
************************************************************************************/