mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-26 06:08:20 +00:00
Add "(void) param;" annotation to address unused parameter warnings. Found with GCC's warning -Wunused-parameter.
299 lines
8.3 KiB
C
299 lines
8.3 KiB
C
/* SPDX-License-Identifier: GPL-2.0+-with-RTEMS-exception */
|
|
|
|
/*
|
|
* console driver for RTL22xx UARTs
|
|
*
|
|
* If you want the driver to be interrupt driven, you
|
|
* need to write the ISR, and in the ISR insert the
|
|
* chars into termios's queue.
|
|
*/
|
|
|
|
/*
|
|
* Copyright (c) By ray <rayx.cn@gmail.com>
|
|
*
|
|
* 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> /* Must be before libio.h */
|
|
#include <rtems/libio.h>
|
|
#include <termios.h>
|
|
#include <rtems/bspIo.h>
|
|
|
|
/* Put the CPU (or UART) specific header file #include here */
|
|
#include <lpc22xx.h>
|
|
#include "lpc22xx_uart.h"
|
|
|
|
#include <libchip/serial.h>
|
|
#include <libchip/sersupp.h>
|
|
|
|
/* How many serial ports? */
|
|
#define NUM_DEVS 1
|
|
|
|
int dbg_dly;
|
|
|
|
/* static function prototypes */
|
|
static int uart_first_open(int major, int minor, void *arg);
|
|
static int uart_last_close(int major, int minor, void *arg);
|
|
static int uart_read(int minor);
|
|
static ssize_t uart_write(int minor, const char *buf, size_t len);
|
|
static void uart_init(int minor);
|
|
static void uart_write_polled(int minor, char c);
|
|
static int uart_set_attributes(int minor, const struct termios *t);
|
|
|
|
/* These are used by code in console.c */
|
|
unsigned long Console_Configuration_Count = NUM_DEVS;
|
|
|
|
/* Pointers to functions for handling the UART. */
|
|
const console_fns uart_fns = {
|
|
libchip_serial_default_probe,
|
|
uart_first_open,
|
|
uart_last_close,
|
|
uart_read,
|
|
uart_write,
|
|
uart_init,
|
|
uart_write_polled, /* not used in this driver */
|
|
uart_set_attributes,
|
|
FALSE /* TRUE if interrupt driven, FALSE if not. */
|
|
};
|
|
|
|
/*
|
|
* There's one item in array for each UART.
|
|
*
|
|
* Some of these fields are marked "NOT USED". They are not used
|
|
* by console.c, but may be used by drivers in libchip
|
|
*/
|
|
console_tbl Console_Configuration_Ports[] = {
|
|
{
|
|
"/dev/com0", /* sDeviceName */
|
|
SERIAL_CUSTOM, /* deviceType */
|
|
&uart_fns, /* pDeviceFns */
|
|
NULL, /* deviceProbe */
|
|
NULL, /* pDeviceFlow */
|
|
0, /* ulMargin - NOT USED */
|
|
0, /* ulHysteresis - NOT USED */
|
|
NULL, /* pDeviceParams */
|
|
0, /* ulCtrlPort1 - NOT USED */
|
|
0, /* ulCtrlPort2 - NOT USED */
|
|
0, /* ulDataPort - NOT USED */
|
|
NULL, /* getRegister - NOT USED */
|
|
NULL, /* setRegister - NOT USED */
|
|
NULL, /* getData - NOT USED */
|
|
NULL, /* setData - NOT USED */
|
|
0, /* ulClock - NOT USED */
|
|
0 /* ulIntVector - NOT USED */
|
|
}
|
|
#if 0
|
|
{
|
|
"/dev/com1", /* sDeviceName */
|
|
SERIAL_CUSTOM, /* deviceType */
|
|
&uart_fns, /* pDeviceFns */
|
|
NULL, /* deviceProbe */
|
|
NULL, /* pDeviceFlow */
|
|
0, /* ulMargin - NOT USED */
|
|
0, /* ulHysteresis - NOT USED */
|
|
NULL, /* pDeviceParams */
|
|
0, /* ulCtrlPort1 - NOT USED */
|
|
0, /* ulCtrlPort2 - NOT USED */
|
|
0, /* ulDataPort - NOT USED */
|
|
NULL, /* getRegister - NOT USED */
|
|
NULL, /* setRegister - NOT USED */
|
|
NULL, /* getData - NOT USED */
|
|
NULL, /* setData - NOT USED */
|
|
0, /* ulClock - NOT USED */
|
|
0 /* ulIntVector - NOT USED */
|
|
}
|
|
#endif
|
|
};
|
|
|
|
/*
|
|
* This is called the first time each device is opened. If the driver
|
|
* is interrupt driven, you should enable interrupts here. Otherwise,
|
|
* it's probably safe to do nothing.
|
|
*
|
|
* Since micromonitor already set up the UART, we do nothing.
|
|
*/
|
|
static int uart_first_open(int major, int minor, void *arg)
|
|
{
|
|
(void) major;
|
|
(void) minor;
|
|
(void) arg;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* This is called the last time each device is closed. If the driver
|
|
* is interrupt driven, you should disable interrupts here. Otherwise,
|
|
* it's probably safe to do nothing.
|
|
*/
|
|
static int uart_last_close(int major, int minor, void *arg)
|
|
{
|
|
(void) major;
|
|
(void) minor;
|
|
(void) arg;
|
|
|
|
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 uart_read(int minor)
|
|
{
|
|
char c;
|
|
|
|
switch (minor) {
|
|
case 0:
|
|
if (U0LSR & ULSR_RDR) {
|
|
c = U0RBR;
|
|
return c;
|
|
}
|
|
return -1;
|
|
case 1:
|
|
if (U1LSR & ULSR_RDR) {
|
|
c = U1RBR;
|
|
return c;
|
|
}
|
|
return -1;
|
|
default:
|
|
break;
|
|
}
|
|
printk("Unknown console minor number %d\n", minor);
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* Write buffer to UART
|
|
*
|
|
* return 1 on success, -1 on error
|
|
*/
|
|
static ssize_t uart_write(int minor, const char *buf, size_t len)
|
|
{
|
|
size_t i;
|
|
|
|
switch (minor) {
|
|
case 0:
|
|
for (i = 0; i < len; i++) {
|
|
while (!(U0LSR & ULSR_THRE)) /* wait for TX buffer to empty*/
|
|
continue; /* also either WDOG() or swap()*/
|
|
U0THR = (char) buf[i];
|
|
}
|
|
break;
|
|
case 1:
|
|
for (i = 0; i < len; i++) {
|
|
while (!(U0LSR & ULSR_THRE)) /* wait for TX buffer to empty*/
|
|
continue; /* also either WDOG() or swap()*/
|
|
U0THR = (char) buf[i];
|
|
}
|
|
break;
|
|
default:
|
|
printk("Unknown console minor number %d\n", minor);
|
|
return -1;
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
/* Set up the UART. */
|
|
static void uart_init(int minor)
|
|
{
|
|
(void) minor;
|
|
|
|
#if 0 //init will be done in bspstart.c
|
|
int baud=6;
|
|
int mode =0x03;
|
|
if(minor==0){
|
|
// set port pins for UART0
|
|
PINSEL0 = (PINSEL0 & ~U0_PINMASK) | U0_PINSEL;
|
|
|
|
U0IER = 0x00; // disable all interrupts
|
|
|
|
// set the baudrate
|
|
U0LCR = 1<<7; // select divisor latches
|
|
U0DLL = (uint8_t)baud; // set for baud low byte
|
|
U0DLM = (uint8_t)(baud >> 8); // set for baud high byte
|
|
|
|
// set the number of characters and other
|
|
// user specified operating parameters
|
|
U0LCR = (mode & ~ULCR_DLAB_ENABLE);
|
|
U0FCR = mode>>8; /*fifo mode*/
|
|
|
|
// set port pins for UART1
|
|
PINSEL0 = (PINSEL0 & ~U1_PINMASK) | U1_PINSEL;
|
|
|
|
U1IER = 0x00; // disable all interrupts
|
|
}else if(minor==1){
|
|
// set the baudrate
|
|
U1LCR = ULCR_DLAB_ENABLE; // select divisor latches
|
|
U1DLL = (uint8_t)baud; // set for baud low byte
|
|
U1DLM = (uint8_t)(baud >> 8); // set for baud high byte
|
|
|
|
// set the number of characters and other
|
|
// user specified operating parameters
|
|
U1LCR = (mode & ~ULCR_DLAB_ENABLE);
|
|
U1FCR = mode>>8;/*fifo mode*/
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
/* I'm not sure this is needed for the shared console driver. */
|
|
static void uart_write_polled(int minor, char c)
|
|
{
|
|
uart_write(minor, &c, 1);
|
|
}
|
|
|
|
/* This is for setting baud rate, bits, etc. */
|
|
static int uart_set_attributes(int minor, const struct termios *t)
|
|
{
|
|
(void) minor;
|
|
(void) t;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Write a character to the console. This is used by printk() and
|
|
* maybe other low level functions. It should not use interrupts or any
|
|
* RTEMS system calls. It needs to be very simple
|
|
*/
|
|
static void _BSP_put_char( char c )
|
|
{
|
|
uart_write_polled(0, c);
|
|
}
|
|
|
|
BSP_output_char_function_type BSP_output_char = _BSP_put_char;
|
|
|
|
static int _BSP_get_char(void)
|
|
{
|
|
return uart_read(0);
|
|
}
|
|
|
|
BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char;
|
|
|
|
/*
|
|
* init USART 0: 8 bit, 1 Stop,No checkout, BPS115200
|
|
*/
|
|
void UART0_Ini(void)
|
|
{
|
|
long Fdiv;
|
|
int i;
|
|
|
|
PINSEL0 = 0x00000005; // I/O to UART0
|
|
U0LCR = 0x83; // DLAB = 1
|
|
Fdiv = (Fpclk >>4) / UART_BPS; // configure BPS
|
|
U0DLM = Fdiv/256;
|
|
U0DLL = Fdiv%256;
|
|
U0LCR = 0x03;
|
|
|
|
for(i=0;i<10;i++){
|
|
U0THR = 67; //send a C to see if is OK
|
|
while ( (U0LSR&0x40)==0 );
|
|
}
|
|
}
|