aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ports/ARM7-LPC214x/GCC/lpc214x_serial.c44
-rw-r--r--ports/ARM7-LPC214x/GCC/lpc214x_serial.h17
-rw-r--r--readme.txt4
-rw-r--r--src/include/inline.h2
4 files changed, 62 insertions, 5 deletions
diff --git a/ports/ARM7-LPC214x/GCC/lpc214x_serial.c b/ports/ARM7-LPC214x/GCC/lpc214x_serial.c
index e3f5e4040..71dbc0b7b 100644
--- a/ports/ARM7-LPC214x/GCC/lpc214x_serial.c
+++ b/ports/ARM7-LPC214x/GCC/lpc214x_serial.c
@@ -22,8 +22,6 @@
#include "lpc214x.h"
#include "lpc214x_serial.h"
-#define SERIAL_BUFFERS_SIZE 128
-
FullDuplexDriver COM1;
BYTE8 ib1[SERIAL_BUFFERS_SIZE];
BYTE8 ob1[SERIAL_BUFFERS_SIZE];
@@ -68,16 +66,28 @@ static void ServeInterrupt(UART *u, FullDuplexDriver *com) {
break;
case IIR_SRC_TX:
{
+#ifdef FIFO_PRELOAD
+ int i = 0;
+ while (i < FIFO_PRELOAD) {
+ t_msg b = chFDDRequestDataI(com);
+ if (b < Q_OK) {
+ u->UART_IER &= ~IER_THRE;
+ break;
+ }
+ u->UART_THR = b;
+ i++;
+ }
+#else
t_msg b = chFDDRequestDataI(com);
if (b < Q_OK)
u->UART_IER &= ~IER_THRE;
else
u->UART_THR = b;
+#endif
}
default:
u->UART_THR;
u->UART_RBR;
- u->UART_IIR;
}
}
}
@@ -89,8 +99,20 @@ static void ServeInterrupt(UART *u, FullDuplexDriver *com) {
static void OutNotify1(void) {
UART *u = U0Base;
- if (u->UART_LSR & LSR_THRE)
+ if (u->UART_LSR & LSR_THRE) {
+#ifdef FIFO_PRELOAD
+ int i = 0;
+ while (i < FIFO_PRELOAD) {
+ t_msg b = chOQGetI(&COM1.sd_oqueue);
+ if (b < Q_OK)
+ break;
+ u->UART_THR = b;
+ i++;
+ }
+#else
u->UART_THR = chOQGetI(&COM1.sd_oqueue);
+#endif
+ }
u->UART_IER |= IER_THRE;
}
@@ -101,8 +123,20 @@ static void OutNotify1(void) {
static void OutNotify2(void) {
UART *u = U1Base;
- if (u->UART_LSR & LSR_THRE)
+ if (u->UART_LSR & LSR_THRE) {
+#ifdef FIFO_PRELOAD
+ int i = 0;
+ while (i < FIFO_PRELOAD) {
+ t_msg b = chOQGetI(&COM2.sd_oqueue);
+ if (b < Q_OK)
+ break;
+ u->UART_THR = b;
+ i++;
+ }
+#else
u->UART_THR = chOQGetI(&COM2.sd_oqueue);
+#endif
+ }
u->UART_IER |= IER_THRE;
}
diff --git a/ports/ARM7-LPC214x/GCC/lpc214x_serial.h b/ports/ARM7-LPC214x/GCC/lpc214x_serial.h
index 1eaba687b..1ee910b4a 100644
--- a/ports/ARM7-LPC214x/GCC/lpc214x_serial.h
+++ b/ports/ARM7-LPC214x/GCC/lpc214x_serial.h
@@ -20,6 +20,23 @@
#ifndef _LPC214x_SERIAL_H_
#define _LPC214x_SERIAL_H_
+/*
+ * Configuration parameter, this values defines how many bytes are preloaded
+ * in the HW transmit FIFO for each interrupt, the maximum value is 16 the
+ * minimum is 2.
+ * NOTE: A greater value reduces the number of interrupts generated but can
+ * also increase the worst case interrupt response time.
+ * NOTE: You can undefine the following macro and revert to a simpler code
+ * that will generate an interrupt for each output byte,
+ */
+#define FIFO_PRELOAD 16
+
+/*
+ * Configuration parameter, you can change the depth of the queue buffers
+ * depending on the requirements of your application.
+ */
+#define SERIAL_BUFFERS_SIZE 128
+
void InitSerial(void);
void SetUARTI(UART *u, int speed, int lcr, int fcr);
void UART0IrqHandler(void);
diff --git a/readme.txt b/readme.txt
index 61ae140a4..833f79e88 100644
--- a/readme.txt
+++ b/readme.txt
@@ -47,6 +47,10 @@ AVR-AT90CANx-GCC - Port on AVR AT90CAN128, not complete yet.
- Fixed a minor problem in the interrupt initialization code for the LPC214x
demo, regrouped the VIC code into vic.c/vic.h.
- Fixed a bug into the LPC2148 serial driver (limited to the serial port 2).
+- Implemented HW transmit FIFO preloading in the LPC2142 serial driver in
+ order to minimize the number of interrupts generated, it is possible to
+ disable the feature and return to the old code which is a bit smaller, see
+ the configuration parameters in ./ARM7-LPC214x/GCC/lpc214x_serial.h.
*** 0.3.4 ***
- Fixed a problem in chVTSetI().
diff --git a/src/include/inline.h b/src/include/inline.h
index afcfb9ae3..1982fd075 100644
--- a/src/include/inline.h
+++ b/src/include/inline.h
@@ -22,6 +22,8 @@
/*
* Inlined functions if CH_OPTIMIZE_SPEED is enabled.
+ * Note: static inlined functions do not duplicate the code in every module
+ * this is true for GCC, not sure about other compilers.
*/
#ifdef CH_OPTIMIZE_SPEED
static INLINE void fifo_insert(Thread *tp, ThreadsQueue *tqp) {