Merge branch 'uart', remote branch 'paparazzi/master'

This commit is contained in:
Gautier Hattenberger
2011-01-17 10:49:36 +01:00
8 changed files with 467 additions and 367 deletions
+1
View File
@@ -92,6 +92,7 @@ endif
#
# Telemetry/Datalink
#
ap.srcs += mcu_periph/uart.c
ap.srcs += $(SRC_ARCH)/mcu_periph/uart_arch.c
ap.CFLAGS += -DDOWNLINK -DDOWNLINK_TRANSPORT=PprzTransport
ap.CFLAGS += -DDOWNLINK_DEVICE=$(MODEM_PORT)
@@ -134,6 +134,7 @@ ns_srcs += $(SRC_ARCH)/sys_time_hw.c
# UARTS
#
ns_srcs += mcu_periph/uart.c
ns_srcs += $(SRC_ARCH)/mcu_periph/uart_arch.c
#
+134 -293
View File
@@ -29,27 +29,138 @@
#include "mcu_periph/uart.h"
#include "armVIC.h"
void uart_periph_init_param(struct uart_periph* p, uint16_t baud, uint8_t mode, uint8_t fmode, char * dev) {
((uartRegs_t *)(p->reg_addr))->ier = 0x00; // disable all interrupts
((uartRegs_t *)(p->reg_addr))->iir; // clear interrupt ID
((uartRegs_t *)(p->reg_addr))->rbr; // clear receive register
((uartRegs_t *)(p->reg_addr))->lsr; // clear line status register
// set the baudrate
((uartRegs_t *)(p->reg_addr))->lcr = ULCR_DLAB_ENABLE; // select divisor latches
((uartRegs_t *)(p->reg_addr))->dll = (uint8_t)baud; // set for baud low byte
((uartRegs_t *)(p->reg_addr))->dlm = (uint8_t)(baud >> 8); // set for baud high byte
// set the number of characters and other
// user specified operating parameters
((uartRegs_t *)(p->reg_addr))->lcr = (mode & ~ULCR_DLAB_ENABLE);
((uartRegs_t *)(p->reg_addr))->fcr = fmode;
}
void uart_transmit(struct uart_periph* p, uint8_t data ) {
uint16_t temp;
unsigned cpsr;
temp = (p->tx_insert_idx + 1) % UART_TX_BUFFER_SIZE;
if (temp == p->tx_extract_idx)
return; // no room
cpsr = disableIRQ(); // disable global interrupts
((uartRegs_t *)(p->reg_addr))->ier &= ~UIER_ETBEI; // disable TX interrupts
restoreIRQ(cpsr); // restore global interrupts
// check if in process of sending data
if (p->tx_running) {
// add to queue
p->tx_buf[p->tx_insert_idx] = data;
p->tx_insert_idx = temp;
} else {
// set running flag and write to output register
p->tx_running = 1;
((uartRegs_t *)(p->reg_addr))->thr = data;
}
cpsr = disableIRQ(); // disable global interrupts
((uartRegs_t *)(p->reg_addr))->ier |= UIER_ETBEI; // enable TX interrupts
restoreIRQ(cpsr); // restore global interrupts
}
static inline void uart_ISR(struct uart_periph* p)
{
uint8_t iid;
// loop until not more interrupt sources
while (((iid = ((uartRegs_t *)(p->reg_addr))->iir) & UIIR_NO_INT) == 0)
{
// identify & process the highest priority interrupt
switch (iid & UIIR_ID_MASK)
{
case UIIR_RLS_INT: // Receive Line Status
((uartRegs_t *)(p->reg_addr))->lsr; // read LSR to clear
break;
case UIIR_CTI_INT: // Character Timeout Indicator
case UIIR_RDA_INT: // Receive Data Available
do
{
uint16_t temp;
// calc next insert index & store character
temp = (p->rx_insert_idx + 1) % UART_RX_BUFFER_SIZE;
p->rx_buf[p->rx_insert_idx] = ((uartRegs_t *)(p->reg_addr))->rbr;
// check for more room in queue
if (temp != p->rx_extract_idx)
p->rx_insert_idx = temp; // update insert index
}
while (((uartRegs_t *)(p->reg_addr))->lsr & ULSR_RDR);
break;
case UIIR_THRE_INT: // Transmit Holding Register Empty
while (((uartRegs_t *)(p->reg_addr))->lsr & ULSR_THRE)
{
// check if more data to send
if (p->tx_insert_idx != p->tx_extract_idx)
{
((uartRegs_t *)(p->reg_addr))->thr = p->tx_buf[p->tx_extract_idx];
p->tx_extract_idx++;
p->tx_extract_idx %= UART_TX_BUFFER_SIZE;
}
else
{
// no
p->tx_running = 0; // clear running flag
break;
}
}
break;
default: // Unknown
((uartRegs_t *)(p->reg_addr))->lsr;
((uartRegs_t *)(p->reg_addr))->rbr;
break;
}
}
}
#ifdef USE_UART0
#ifndef UART0_VIC_SLOT
#define UART0_VIC_SLOT 5
#endif
void uart0_ISR(void) __attribute__((naked));
uint8_t uart0_rx_buffer[UART0_RX_BUFFER_SIZE];
uint16_t uart0_rx_insert_idx, uart0_rx_extract_idx;
void uart0_ISR(void) {
// perform proper ISR entry so thumb-interwork works properly
ISR_ENTRY();
uint8_t uart0_tx_buffer[UART0_TX_BUFFER_SIZE];
uint16_t uart0_tx_insert_idx, uart0_tx_extract_idx;
uint8_t uart0_tx_running;
uart_ISR(&uart0);
void uart0_init( void ) {
uart0_init_param(UART0_BAUD, UART_8N1, UART_FIFO_8);
VICVectAddr = 0x00000000; // clear this interrupt from the VIC
ISR_EXIT(); // recover registers and return
}
void uart0_init_param( uint16_t baud, uint8_t mode, uint8_t fmode) {
void uart0_init( void ) {
uart_periph_init(&uart0);
uart0.reg_addr = UART0_BASE;
#ifdef USE_UART0_RX_ONLY
// only use the RX0 P0.1 pin, no TX
PINSEL0 = (PINSEL0 & ~U0_PINMASK_RX) | U0_PINSEL_RX;
@@ -58,20 +169,8 @@ void uart0_init_param( uint16_t baud, uint8_t mode, uint8_t fmode) {
PINSEL0 = (PINSEL0 & ~U0_PINMASK) | U0_PINSEL;
#endif
U0IER = 0x00; // disable all interrupts
U0IIR; // clear interrupt ID
U0RBR; // clear receive register
U0LSR; // clear line status register
// set the baudrate
U0LCR = ULCR_DLAB_ENABLE; // 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 = fmode;
// initialize uart parameters
uart_periph_init_param(&uart0, UART0_BAUD, UART_8N1, UART_FIFO_8, "");
// initialize the interrupt vector
VICIntSelect &= ~VIC_BIT(VIC_UART0); // UART0 selected as IRQ
@@ -79,138 +178,12 @@ void uart0_init_param( uint16_t baud, uint8_t mode, uint8_t fmode) {
_VIC_CNTL(UART0_VIC_SLOT) = VIC_ENABLE | VIC_UART0;
_VIC_ADDR(UART0_VIC_SLOT) = (uint32_t)uart0_ISR; // address of the ISR
// initialize the transmit data queue
uart0_tx_extract_idx = 0;
uart0_tx_insert_idx = 0;
uart0_tx_running = 0;
// initialize the receive data queue
uart0_rx_extract_idx = 0;
uart0_rx_insert_idx = 0;
// enable receiver interrupts
U0IER = UIER_ERBFI;
}
bool_t uart0_check_free_space( uint8_t len) {
int16_t space = uart0_tx_extract_idx - uart0_tx_insert_idx;
if (space <= 0)
space += UART0_TX_BUFFER_SIZE;
return (uint16_t)(space - 1) >= len;
}
void uart0_transmit( unsigned char data ) {
uint16_t temp;
unsigned cpsr;
temp = (uart0_tx_insert_idx + 1) % UART0_TX_BUFFER_SIZE;
if (temp == uart0_tx_extract_idx)
// return -1; // no room
return; // no room
cpsr = disableIRQ(); // disable global interrupts
U0IER &= ~UIER_ETBEI; // disable TX interrupts
restoreIRQ(cpsr); // restore global interrupts
// check if in process of sending data
if (uart0_tx_running)
{
// add to queue
uart0_tx_buffer[uart0_tx_insert_idx] = (uint8_t)data;
uart0_tx_insert_idx = temp;
}
else
{
// set running flag and write to output register
uart0_tx_running = 1;
U0THR = (uint8_t)data;
}
cpsr = disableIRQ(); // disable global interrupts
U0IER |= UIER_ETBEI; // enable TX interrupts
restoreIRQ(cpsr); // restore global interrupts
// return (uint8_t)ch;
}
void uart0_ISR(void)
{
uint8_t iid;
// perform proper ISR entry so thumb-interwork works properly
ISR_ENTRY();
// loop until not more interrupt sources
while (((iid = U0IIR) & UIIR_NO_INT) == 0)
{
// identify & process the highest priority interrupt
switch (iid & UIIR_ID_MASK)
{
case UIIR_RLS_INT: // Receive Line Status
U0LSR; // read LSR to clear
break;
case UIIR_CTI_INT: // Character Timeout Indicator
case UIIR_RDA_INT: // Receive Data Available
do
{
uint16_t temp;
// calc next insert index & store character
temp = (uart0_rx_insert_idx + 1) % UART0_RX_BUFFER_SIZE;
uart0_rx_buffer[uart0_rx_insert_idx] = U0RBR;
// check for more room in queue
if (temp != uart0_rx_extract_idx)
uart0_rx_insert_idx = temp; // update insert index
}
while (U0LSR & ULSR_RDR);
break;
case UIIR_THRE_INT: // Transmit Holding Register Empty
while (U0LSR & ULSR_THRE)
{
// check if more data to send
if (uart0_tx_insert_idx != uart0_tx_extract_idx)
{
U0THR = uart0_tx_buffer[uart0_tx_extract_idx];
uart0_tx_extract_idx++;
uart0_tx_extract_idx %= UART0_TX_BUFFER_SIZE;
}
else
{
// no
uart0_tx_running = 0; // clear running flag
break;
}
}
break;
default: // Unknown
U0LSR;
U0RBR;
break;
}
}
VICVectAddr = 0x00000000; // clear this interrupt from the VIC
ISR_EXIT(); // recover registers and return
}
#endif /* USE_UART0 */
/*
*
* UART1 handling functions - those are pale copies of UART0 ones
* We should probably find a better way to make the code configurable
* for both uarts
*
*/
#ifdef USE_UART1
#ifndef UART1_VIC_SLOT
@@ -219,27 +192,21 @@ void uart0_ISR(void)
void uart1_ISR(void) __attribute__((naked));
uint8_t uart1_rx_buffer[UART1_RX_BUFFER_SIZE];
uint16_t uart1_rx_insert_idx, uart1_rx_extract_idx;
void uart1_ISR(void) {
// perform proper ISR entry so thumb-interwork works properly
ISR_ENTRY();
uint8_t uart1_tx_buffer[UART1_TX_BUFFER_SIZE];
uint16_t uart1_tx_insert_idx, uart1_tx_extract_idx;
uint8_t uart1_tx_running;
uart_ISR(&uart1);
VICVectAddr = 0x00000000; // clear this interrupt from the VIC
ISR_EXIT(); // recover registers and return
}
void uart1_init( void ) {
uart1_init_param(UART1_BAUD, UART_8N1, UART_FIFO_8);
}
bool_t uart1_check_free_space( uint8_t len) {
int16_t space = uart1_tx_extract_idx - uart1_tx_insert_idx;
if (space <= 0)
space += UART1_TX_BUFFER_SIZE;
uart_periph_init(&uart1);
uart1.reg_addr = UART1_BASE;
return (uint16_t)(space - 1) >= len;
}
void uart1_init_param( uint16_t baud, uint8_t mode, uint8_t fmode) {
#ifdef USE_UART1_RX_ONLY
// only use the RX1 P0.9 pin, no TX
PINSEL0 = (PINSEL0 & ~U1_PINMASK_RX) | U1_PINSEL_RX;
@@ -248,20 +215,7 @@ void uart1_init_param( uint16_t baud, uint8_t mode, uint8_t fmode) {
PINSEL0 = (PINSEL0 & ~U1_PINMASK) | U1_PINSEL;
#endif
U1IER = 0x00; // disable all interrupts
U1IIR; // clear interrupt ID
U1RBR; // clear receive register
U1LSR; // clear line status register
// 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 = fmode;
uart_periph_init_param(&uart1, UART1_BAUD, UART_8N1, UART_FIFO_8, "");
// initialize the interrupt vector
VICIntSelect &= ~VIC_BIT(VIC_UART1); // UART1 selected as IRQ
@@ -269,122 +223,9 @@ void uart1_init_param( uint16_t baud, uint8_t mode, uint8_t fmode) {
_VIC_CNTL(UART1_VIC_SLOT) = VIC_ENABLE | VIC_UART1;
_VIC_ADDR(UART1_VIC_SLOT) = (uint32_t)uart1_ISR; // address of the ISR
// initialize the transmit data queue
uart1_tx_extract_idx = 0;
uart1_tx_insert_idx = 0;
uart1_tx_running = 0;
// initialize the receive data queue
uart1_rx_extract_idx = 0;
uart1_rx_insert_idx = 0;
// enable receiver interrupts
U1IER = UIER_ERBFI;
}
#endif
void uart1_transmit( unsigned char data ) {
uint16_t temp;
unsigned cpsr;
temp = (uart1_tx_insert_idx + 1) % UART1_TX_BUFFER_SIZE;
if (temp == uart1_tx_extract_idx)
// return -1; // no room
return; // no room
cpsr = disableIRQ(); // disable global interrupts
U1IER &= ~UIER_ETBEI; // disable TX interrupts
restoreIRQ(cpsr); // restore global interrupts
// check if in process of sending data
if (uart1_tx_running)
{
// add to queue
uart1_tx_buffer[uart1_tx_insert_idx] = (uint8_t)data;
uart1_tx_insert_idx = temp;
}
else
{
// set running flag and write to output register
uart1_tx_running = 1;
U1THR = (uint8_t)data;
}
cpsr = disableIRQ(); // disable global interrupts
U1IER |= UIER_ETBEI; // enable TX interrupts
restoreIRQ(cpsr); // restore global interrupts
}
void uart1_ISR(void)
{
uint8_t iid;
// perform proper ISR entry so thumb-interwork works properly
ISR_ENTRY();
// loop until not more interrupt sources
while (((iid = U1IIR) & UIIR_NO_INT) == 0)
{
// identify & process the highest priority interrupt
switch (iid & UIIR_ID_MASK)
{
case UIIR_RLS_INT: // Receive Line Status
U1LSR; // read LSR to clear
break;
case UIIR_CTI_INT: // Character Timeout Indicator
case UIIR_RDA_INT: // Receive Data Available
do
{
uint16_t temp;
// calc next insert index & store character
temp = (uart1_rx_insert_idx + 1) % UART1_RX_BUFFER_SIZE;
uart1_rx_buffer[uart1_rx_insert_idx] = U1RBR;
// check for more room in queue
if (temp != uart1_rx_extract_idx)
uart1_rx_insert_idx = temp; // update insert index
}
while (U1LSR & ULSR_RDR);
break;
case UIIR_THRE_INT: // Transmit Holding Register Empty
while (U1LSR & ULSR_THRE)
{
// check if more data to send
if (uart1_tx_insert_idx != uart1_tx_extract_idx)
{
U1THR = uart1_tx_buffer[uart1_tx_extract_idx];
uart1_tx_extract_idx++;
uart1_tx_extract_idx %= UART1_TX_BUFFER_SIZE;
}
else
{
// no
uart1_tx_running = 0; // clear running flag
break;
}
}
break;
case UIIR_MS_INT: // MODEM Status
U1MSR; // read MSR to clear
break;
default: // Unknown
U1LSR;
U1RBR;
U1MSR;
break;
}
}
VICVectAddr = 0x00000000; // clear this interrupt from the VIC
ISR_EXIT(); // recover registers and return
}
#endif /* USE_UART1 */
@@ -29,11 +29,6 @@
#include "LPC21xx.h"
#include BOARD_CONFIG
#define UART0_RX_BUFFER_SIZE 128 // UART0 receive buffer size
#define UART0_TX_BUFFER_SIZE 128 // UART0 transmit buffer size
#define UART1_RX_BUFFER_SIZE 128 // UART1 receive buffer size
#define UART1_TX_BUFFER_SIZE 128 // UART1 transmit buffer size
#define UART_BAUD(baud) (uint16_t)((PCLK / ((baud) * 16.0)) + 0.5)
#define B1200 UART_BAUD(1200)
@@ -64,33 +59,4 @@
#define UART_FIFO_8 (uint8_t)(UFCR_FIFO_ENABLE + UFCR_FIFO_TRIG8)
#define UART_FIFO_14 (uint8_t)(UFCR_FIFO_ENABLE + UFCR_FIFO_TRIG14)
extern uint16_t uart0_rx_insert_idx, uart0_rx_extract_idx;
extern uint8_t uart0_rx_buffer[UART0_RX_BUFFER_SIZE];
#define Uart0ChAvailable() (uart0_rx_insert_idx != uart0_rx_extract_idx)
#define Uart0Getch() ({\
uint8_t ret = uart0_rx_buffer[uart0_rx_extract_idx]; \
uart0_rx_extract_idx = (uart0_rx_extract_idx + 1)%UART0_RX_BUFFER_SIZE; \
ret; \
})
extern uint16_t uart1_rx_insert_idx, uart1_rx_extract_idx;
extern uint8_t uart1_rx_buffer[UART1_RX_BUFFER_SIZE];
extern void uart1_init_param( uint16_t baud, uint8_t mode, uint8_t fmode);
extern void uart0_init_param( uint16_t baud, uint8_t mode, uint8_t fmode);
#define Uart1ChAvailable() (uart1_rx_insert_idx != uart1_rx_extract_idx)
#define Uart1Getch() ({\
uint8_t ret = uart1_rx_buffer[uart1_rx_extract_idx]; \
uart1_rx_extract_idx = (uart1_rx_extract_idx + 1)%UART1_RX_BUFFER_SIZE; \
ret; \
})
extern uint8_t uart0_tx_running;
extern uint8_t uart1_tx_running;
#endif /* LPC21_UART_ARCH_H */
@@ -0,0 +1,128 @@
/*
* Paparazzi $Id$
*
* Copyright (C) 2009 Antoine Drouin <poinix@gmail.com>
*
* This file is part of paparazzi.
*
* paparazzi is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* paparazzi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "mcu_periph/uart.h"
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fms/fms_serial_port.h"
void uart_periph_init_param(struct uart_periph* p, uint16_t baud, uint8_t mode, uint8_t fmode, char * dev) {
struct FmsSerialPort* fmssp;
// close serial port if already open
if (p->reg_addr != NULL) {
fmssp = (struct FmsSerialPort*)(p->reg_addr);
serial_port_close(fmssp);
serial_port_free(fmssp);
}
// open serial port
fmssp = serial_port_new();
// use register address to store SerialPort structure pointer...
p->reg_addr = (void*)fmssp;
//TODO: set device name in application and pass as argument
printf("opening %s on uart0 at %d\n",dev,baud);
serial_port_open_raw(fmssp,dev,baud);
}
void uart_transmit(struct uart_periph* p, uint8_t data ) {
uint16_t temp = (p->tx_insert_idx + 1) % UART_TX_BUFFER_SIZE;
if (temp == p->tx_extract_idx)
return; // no room
// check if in process of sending data
if (p->tx_running) { // yes, add to queue
p->tx_buf[p->tx_insert_idx] = data;
p->tx_insert_idx = temp;
}
else { // no, set running flag and write to output register
p->tx_running = TRUE;
struct FmsSerialPort* fmssp = (struct FmsSerialPort*)(p->reg_addr);
write((int)(fmssp->fd),&data,1);
//printf("w %x\n",data);
}
}
static inline void uart_handler(struct uart_periph* p) {
unsigned char c='D';
if (p->reg_addr == NULL) return; // device not initialized ?
struct FmsSerialPort* fmssp = (struct FmsSerialPort*)(p->reg_addr);
int fd = fmssp->fd;
// check if more data to send
if (p->tx_insert_idx != p->tx_extract_idx) {
write(fd,&(p->tx_buf[p->tx_extract_idx]),1);
//printf("w %x\n",p->tx_buf[p->tx_extract_idx]);
p->tx_extract_idx++;
p->tx_extract_idx %= UART_TX_BUFFER_SIZE;
}
else {
p->tx_running = FALSE; // clear running flag
}
if(read(fd,&c,1) > 0){
//printf("r %x %c\n",c,c);
uint16_t temp = (p->rx_insert_idx + 1) % UART_RX_BUFFER_SIZE;
p->rx_buf[p->rx_insert_idx] = c;
// check for more room in queue
if (temp != p->rx_extract_idx)
p->rx_insert_idx = temp; // update insert index
}
}
#ifdef USE_UART0
void uart0_init( void ) {
uart_periph_init(&uart0);
uart_periph_init_param(&uart0,UART0_BAUD,NULL,NULL,UART0_DEV);
}
void uart0_handler(void) {
uart_handler(&uart0);
}
#endif /* USE_UART0 */
#ifdef USE_UART1
void uart1_init( void ) {
uart_periph_init(&uart1);
uart_periph_init_param(&uart1,UART1_BAUD,NULL,NULL,UART1_DEV);
}
void uart1_handler(void) {
uart_handler(&uart1);
}
#endif /* USE_UART1 */
@@ -0,0 +1,72 @@
/*
* $Id$
*
* Copyright (C) 2009 Antoine Drouin <poinix@gmail.com>
*
* This file is part of paparazzi.
*
* paparazzi is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* paparazzi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef UART_ARCH_H
#define UART_ARCH_H
#include "std.h"
//coment to avoid redefinition
/*#define B9600 9600
#define B38400 38400
#define B57600 57600
#define B115200 115200
*/
//junk for gps_configure_uart in gps_ubx.c to compile
#define UART_8N1 1
#define UART_FIFO_8 1
#define UART_BAUD(baud) (baud)
#define Uart1_init uart1_init()
#define Uart2_init uart2_init()
#define Uart3_init uart3_init()
#define Uart5_init uart5_init()
#define UART1_irq_handler usart1_irq_handler
#define UART2_irq_handler usart2_irq_handler
#define UART3_irq_handler usart3_irq_handler
#define UART5_irq_handler usart5_irq_handler
#if defined USE_UART0 || OVERRIDE_UART0_IRQ_HANDLER
extern void uart0_handler(void);
#endif
#ifdef USE_UART0
void uart0_init( void );
#endif /* USE_UART0 */
#if defined USE_UART1 || OVERRIDE_UART1_IRQ_HANDLER
extern void uart1_handler(void);
#endif
#ifdef USE_UART1
void uart1_init( void );
#endif /* USE_UART1 */
#endif /* UART_ARCH_H */
+57
View File
@@ -0,0 +1,57 @@
/*
* Paparazzi $Id$
*
* Copyright (C) 2010 The Paparazzi Team
*
* This file is part of paparazzi.
*
* paparazzi is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* paparazzi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include "mcu_periph/uart.h"
#ifdef USE_UART0
struct uart_periph uart0;
#endif
#ifdef USE_UART1
struct uart_periph uart1;
#endif
#ifdef USE_UART2
struct uart_periph uart2;
#endif
#ifdef USE_UART3
struct uart_periph uart3;
#endif
void uart_periph_init(struct uart_periph* p) {
p->rx_insert_idx = 0;
p->rx_extract_idx = 0;
p->tx_insert_idx = 0;
p->tx_extract_idx = 0;
p->tx_running = FALSE;
}
bool_t uart_check_free_space(struct uart_periph* p, uint8_t len) {
int16_t space = p->tx_extract_idx - p->tx_insert_idx;
if (space <= 0)
space += UART_TX_BUFFER_SIZE;
return (uint16_t)(space - 1) >= len;
}
+74 -40
View File
@@ -33,22 +33,53 @@
#include "mcu_periph/uart_arch.h"
#include "std.h"
#define UART_RX_BUFFER_SIZE 128
#define UART_TX_BUFFER_SIZE 128
/**
* UART peripheral
*/
struct uart_periph {
/* Receive buffer */
uint8_t rx_buf[UART_RX_BUFFER_SIZE];
uint16_t rx_insert_idx;
uint16_t rx_extract_idx;
/* Transmit buffer */
uint8_t tx_buf[UART_RX_BUFFER_SIZE];
uint16_t tx_insert_idx;
uint16_t tx_extract_idx;
uint8_t tx_running;
/* UART Register */
void* reg_addr;
};
extern void uart_periph_init(struct uart_periph* p);
extern void uart_periph_init_param(struct uart_periph* p, uint16_t baud, uint8_t mode, uint8_t fmode, char * dev);
extern void uart_transmit(struct uart_periph* p, uint8_t data);
extern bool_t uart_check_free_space(struct uart_periph* p, uint8_t len);
#define UartChAvailable(_p) (_p.rx_insert_idx != _p.rx_extract_idx)
#define UartGetch(_p) ({ \
uint8_t ret = _p.rx_buf[_p.rx_extract_idx]; \
_p.rx_extract_idx = (_p.rx_extract_idx + 1)%UART_RX_BUFFER_SIZE; \
ret; \
})
#ifdef USE_UART0
extern struct uart_periph uart0;
extern void uart0_init(void);
extern void uart0_init( void );
extern void uart0_transmit( uint8_t data );
extern bool_t uart0_check_free_space( uint8_t len);
#define Uart0Init uart0_init
#define Uart0CheckFreeSpace(_x) uart0_check_free_space(_x)
#define Uart0Transmit(_x) uart0_transmit(_x)
#define Uart0Init() uart_periph_init(&uart0)
#define Uart0CheckFreeSpace(_x) uart_check_free_space(&uart0, _x)
#define Uart0Transmit(_x) uart_transmit(&uart0, _x)
#define Uart0SendMessage() {}
#define Uart0ChAvailable() UartChAvailable(uart0)
#define Uart0Getch() UartGetch(uart0)
#define Uart0TxRunning uart0.tx_running
#define Uart0InitParam(_b, _m, _fm) uart_periph_init_param(&uart0, _b, _m, _fm, "")
#define Uart0TxRunning uart0_tx_running
#define Uart0InitParam uart0_init_param
/* I want to trigger USE_UART and generate macros with the makefile same variable */
#define UART0Init Uart0Init
#define UART0CheckFreeSpace Uart0CheckFreeSpace
#define UART0Transmit Uart0Transmit
@@ -56,21 +87,20 @@ extern bool_t uart0_check_free_space( uint8_t len);
#define UART0ChAvailable Uart0ChAvailable
#define UART0Getch Uart0Getch
#endif /* USE_UART0 */
#endif // USE_UART0
#ifdef USE_UART1
extern struct uart_periph uart1;
extern void uart1_init(void);
extern void uart1_init( void );
extern void uart1_transmit( uint8_t data );
extern bool_t uart1_check_free_space( uint8_t len);
#define Uart1Init uart1_init
#define Uart1CheckFreeSpace(_x) uart1_check_free_space(_x)
#define Uart1Transmit(_x) uart1_transmit(_x)
#define Uart1Init() uart_periph_init(&uart1)
#define Uart1CheckFreeSpace(_x) uart_check_free_space(&uart1, _x)
#define Uart1Transmit(_x) uart_transmit(&uart1, _x)
#define Uart1SendMessage() {}
#define Uart1TxRunning uart1_tx_running
#define Uart1InitParam uart1_init_param
#define Uart1ChAvailable() UartChAvailable(uart1)
#define Uart1Getch() UartGetch(uart1)
#define Uart1TxRunning uart1.tx_running
#define Uart1InitParam(_b, _m, _fm) uart_periph_init_param(&uart1, _b, _m, _fm, "")
#define UART1Init Uart1Init
#define UART1CheckFreeSpace Uart1CheckFreeSpace
@@ -79,18 +109,20 @@ extern bool_t uart1_check_free_space( uint8_t len);
#define UART1ChAvailable Uart1ChAvailable
#define UART1Getch Uart1Getch
#endif /* USE_UART1 */
#endif // USE_UART1
#ifdef USE_UART2
extern struct uart_periph uart2;
extern void uart2_init(void);
extern void uart2_init( void );
extern void uart2_transmit( uint8_t data );
extern bool_t uart2_check_free_space( uint8_t len);
#define Uart2Init uart2_init
#define Uart2CheckFreeSpace(_x) uart2_check_free_space(_x)
#define Uart2Transmit(_x) uart2_transmit(_x)
#define Uart2Init() uart_periph_init(&uart2)
#define Uart2CheckFreeSpace(_x) uart_check_free_space(&uart2, _x)
#define Uart2Transmit(_x) uart_transmit(&uart2, _x)
#define Uart2SendMessage() {}
#define Uart2ChAvailable() UartChAvailable(uart2)
#define Uart2Getch() UartGetch(uart2)
#define Uart2TxRunning uart2.tx_running
#define Uart2InitParam(_b, _m, _fm) uart_periph_init_param(&uart2, _b, _m, _fm, "")
#define UART2Init Uart2Init
#define UART2CheckFreeSpace Uart2CheckFreeSpace
@@ -99,18 +131,20 @@ extern bool_t uart2_check_free_space( uint8_t len);
#define UART2ChAvailable Uart2ChAvailable
#define UART2Getch Uart2Getch
#endif /* USE_UART2 */
#endif // USE_UART2
#ifdef USE_UART3
extern struct uart_periph uart3;
extern void uart3_init(void);
extern void uart3_init( void );
extern void uart3_transmit( uint8_t data );
extern bool_t uart3_check_free_space( uint8_t len);
#define Uart3Init uart3_init
#define Uart3CheckFreeSpace(_x) uart3_check_free_space(_x)
#define Uart3Transmit(_x) uart3_transmit(_x)
#define Uart3Init() uart_periph_init(&uart3)
#define Uart3CheckFreeSpace(_x) uart_check_free_space(&uart3, _x)
#define Uart3Transmit(_x) uart_transmit(&uart3, _x)
#define Uart3SendMessage() {}
#define Uart3ChAvailable() UartChAvailable(uart3)
#define Uart3Getch() UartGetch(uart3)
#define Uart3TxRunning uart3.tx_running
#define Uart3InitParam(_b, _m, _fm) uart_periph_init_param(&uart3, _b, _m, _fm, "")
#define UART3Init Uart3Init
#define UART3CheckFreeSpace Uart3CheckFreeSpace
@@ -119,6 +153,6 @@ extern bool_t uart3_check_free_space( uint8_t len);
#define UART3ChAvailable Uart3ChAvailable
#define UART3Getch Uart3Getch
#endif /* USE_UART3 */
#endif // USE_UART3
#endif /* MCU_PERIPH_UART_H */
#endif /* UART_H */