mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-11-16 12:34:45 +00:00
Add "(void) param;" annotation to address unused parameter warnings. Found with GCC's warning -Wunused-parameter.
270 lines
5.9 KiB
C
270 lines
5.9 KiB
C
/* SPDX-License-Identifier: GPL-2.0+-with-RTEMS-exception */
|
|
|
|
/*
|
|
* Driver for AT91RM9200 USART ports
|
|
*/
|
|
|
|
/*
|
|
* COPYRIGHT (c) 2006-2009.
|
|
* NCB - Sistemas Embarcados Ltda. (Brazil)
|
|
* Fernando Nicodemos <fgnicodemos@terra.com.br>
|
|
*
|
|
* and
|
|
*
|
|
* COPYRIGHT (c) 1989-2009.
|
|
* On-Line Applications Research Corporation (OAR).
|
|
*
|
|
* The license and distribution terms for this file may be
|
|
* found in the file LICENSE in this distribution or at
|
|
* http://www.rtems.org/license/LICENSE.
|
|
*/
|
|
|
|
#include <bsp.h>
|
|
#include <rtems/libio.h>
|
|
#include <termios.h>
|
|
|
|
#include <at91rm9200.h>
|
|
#include <at91rm9200_usart.h>
|
|
#include <at91rm9200_pmc.h>
|
|
#include <rtems/bspIo.h>
|
|
#include <libchip/serial.h>
|
|
#include <libchip/sersupp.h>
|
|
|
|
/* static function prototypes */
|
|
static int usart_first_open(int major, int minor, void *arg);
|
|
static int usart_last_close(int major, int minor, void *arg);
|
|
static int usart_read_polled(int minor);
|
|
static ssize_t usart_write_polled_support(int minor, const char *buf, size_t len);
|
|
static void usart_init(int minor);
|
|
static void usart_write_polled(int minor, char c);
|
|
static int usart_set_attributes(int minor, const struct termios *t);
|
|
at91rm9200_usart_regs_t *usart_get_base(int minor);
|
|
|
|
/* Pointers to functions for handling the UART polled. */
|
|
const console_fns usart_polling_fns = {
|
|
libchip_serial_default_probe, /* deviceProbe */
|
|
usart_first_open, /* deviceFirstOpen */
|
|
usart_last_close, /* deviceLastClose */
|
|
usart_read_polled, /* deviceRead */
|
|
usart_write_polled_support, /* deviceWrite */
|
|
usart_init, /* deviceInitialize */
|
|
usart_write_polled, /* deviceWritePolled */
|
|
usart_set_attributes, /* deviceSetAttributes */
|
|
FALSE /* TRUE if interrupt driven, FALSE if not. */
|
|
};
|
|
|
|
at91rm9200_usart_regs_t *usart_get_base(int minor)
|
|
{
|
|
console_tbl *console_entry;
|
|
at91rm9200_usart_regs_t *port;
|
|
|
|
console_entry = BSP_get_uart_from_minor(minor);
|
|
|
|
if (console_entry == NULL)
|
|
return 0;
|
|
|
|
port = (at91rm9200_usart_regs_t *) console_entry->ulCtrlPort1;
|
|
//printk( "minor=%d entry=%p port=%p\n", minor, console_entry, port );
|
|
|
|
return port;
|
|
}
|
|
|
|
/*
|
|
* Functions called via callbacks (i.e. the ones in uart_fns
|
|
*/
|
|
|
|
/*
|
|
* This is called the first time each device is opened. Since
|
|
* the driver is polled, we don't have to do anything. If the driver
|
|
* were interrupt driven, we'd enable interrupts here.
|
|
*/
|
|
static int usart_first_open(int major, int minor, void *arg)
|
|
{
|
|
(void) major;
|
|
(void) arg;
|
|
|
|
at91rm9200_usart_regs_t *usart;
|
|
|
|
usart = usart_get_base(minor);
|
|
if ( !usart )
|
|
return -1;
|
|
|
|
/* XXX port isn't being initialized or enabled */
|
|
|
|
/* XXX I hope this is enough */
|
|
usart->cr = (US_CR_RXEN | US_CR_TXEN);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* This is called the last time each device is closed. Since
|
|
* the driver is polled, we don't have to do anything. If the driver
|
|
* were interrupt driven, we'd disable interrupts here.
|
|
*/
|
|
static int usart_last_close(int major, int minor, void *arg)
|
|
{
|
|
(void) major;
|
|
(void) arg;
|
|
|
|
at91rm9200_usart_regs_t *usart;
|
|
|
|
usart = usart_get_base(minor);
|
|
if ( !usart )
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Read one character from UART.
|
|
*
|
|
* return -1 if there's no data, otherwise return
|
|
* the character in lowest 8 bits of returned int.
|
|
*/
|
|
static int usart_read_polled(int minor)
|
|
{
|
|
at91rm9200_usart_regs_t *usart;
|
|
|
|
usart = usart_get_base(minor);
|
|
if ( !usart )
|
|
return -1;
|
|
|
|
/* if nothing ready return -1 */
|
|
if ( (usart->sr & US_IER_RXRDY) == 0 )
|
|
return -1;
|
|
|
|
return usart->rhr;
|
|
}
|
|
|
|
|
|
/*
|
|
* Write character out
|
|
*/
|
|
static void usart_write_polled(int minor, char c)
|
|
{
|
|
at91rm9200_usart_regs_t *usart;
|
|
|
|
usart = usart_get_base(minor);
|
|
if ( !usart )
|
|
return;
|
|
|
|
/* delay until TX empty */
|
|
while ( (usart->sr & US_IER_TXEMPTY) == 0 )
|
|
;
|
|
|
|
usart->thr = c;
|
|
}
|
|
|
|
/*
|
|
* Write buffer to UART
|
|
*
|
|
* return 1 on success, -1 on error
|
|
*/
|
|
static ssize_t usart_write_polled_support(int minor, const char *buf, size_t len)
|
|
{
|
|
at91rm9200_usart_regs_t *usart;
|
|
int nwrite=0;
|
|
|
|
/*
|
|
* Verify the minor number
|
|
*/
|
|
usart = usart_get_base(minor);
|
|
if ( !usart )
|
|
return -1;
|
|
|
|
/*
|
|
* poll each byte in the string out of the port.
|
|
*/
|
|
while (nwrite < len) {
|
|
usart_write_polled(minor, *buf++);
|
|
nwrite++;
|
|
}
|
|
|
|
/*
|
|
* return the number of bytes written.
|
|
*/
|
|
return nwrite;
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
/* Set up the UART. */
|
|
static void usart_init(int minor)
|
|
{
|
|
at91rm9200_usart_regs_t *usart;
|
|
|
|
usart = usart_get_base(minor);
|
|
if ( !usart )
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
/* This is for setting baud rate, bits, etc. */
|
|
static int usart_set_attributes(int minor, const struct termios *t)
|
|
{
|
|
uint32_t brgr;
|
|
uint32_t mode, baud, baud_requested;
|
|
at91rm9200_usart_regs_t *usart;
|
|
|
|
usart = usart_get_base(minor);
|
|
if ( !usart )
|
|
return -1;
|
|
|
|
/* Get current mode register */
|
|
mode = usart->mr & ~(US_MR_USMODE | US_MR_USCLKS | US_MR_CHRL
|
|
| US_MR_PAR | US_MR_NBSTOP);
|
|
|
|
/* Byte size */
|
|
switch (t->c_cflag & CSIZE){
|
|
case CS5:
|
|
mode |= US_MR_CHRL_5;
|
|
break;
|
|
case CS6:
|
|
mode |= US_MR_CHRL_6;
|
|
break;
|
|
case CS7:
|
|
mode |= US_MR_CHRL_7;
|
|
break;
|
|
default:
|
|
mode |= US_MR_CHRL_8;
|
|
break;
|
|
}
|
|
|
|
/* Stop bits */
|
|
if (t->c_cflag & CSTOPB){
|
|
mode |= US_MR_NBSTOP_2; /* 2 stop bits */
|
|
} else
|
|
mode |= US_MR_NBSTOP_1; /* 1 stop bits */
|
|
|
|
/* Parity */
|
|
if (t->c_cflag & PARENB){
|
|
/* Mark or Space parity */
|
|
if (t->c_cflag & PARODD){
|
|
mode |= US_MR_PAR_ODD;
|
|
} else
|
|
mode |= US_MR_PAR_EVEN;
|
|
} else
|
|
mode |= US_MR_PAR_NONE;
|
|
|
|
baud_requested = t->c_ospeed;
|
|
|
|
/* If not, set the dbgu console baud as USART baud default */
|
|
if (!baud_requested)
|
|
baud_requested = BSP_get_baud();
|
|
|
|
baud = rtems_termios_baud_to_number(baud_requested);
|
|
|
|
brgr = (at91rm9200_get_mck() / 16) / baud;
|
|
|
|
if (brgr > 65535){ /* BRGR is 16-bit, so switch to slower clock */
|
|
brgr /= 8;
|
|
mode |= US_MR_USCLKS_MCK_DIV8;
|
|
}
|
|
|
|
usart->mr = mode;
|
|
usart->brgr = brgr;
|
|
return 0;
|
|
}
|