mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-06-06 16:58:48 +08:00
Merge branch 'uart', remote branch 'paparazzi/master'
This commit is contained in:
@@ -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
|
||||
|
||||
#
|
||||
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user