Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of MODSERIAL by
Revision 2:b936b4acbd92, committed 2010-11-21
- Comitter:
- AjK
- Date:
- Sun Nov 21 03:31:51 2010 +0000
- Parent:
- 1:b7e435fbfe8e
- Child:
- 3:0f10f536456e
- Commit message:
- 1.4
Changed in this revision
--- a/ChangeLog.c Sun Nov 21 02:15:07 2010 +0000
+++ b/ChangeLog.c Sun Nov 21 03:31:51 2010 +0000
@@ -1,5 +1,21 @@
/* $Id:$
+
+1.3 - 21/11/2010
+
+ * Fixed a macro problem with txIsBusy()
+ * Started adding code to use "block data" sending using DMA
+1.2 - 21/11/2010
+
+ * Removed unsed variables from flushBuffer()
+ * Fixed a bug where both RX AND TX fifos are cleared/reset
+ when just TX OR RX should be cleared.
+ * Fixed a bug that cleared IIR when in fact it should be left
+ alone so that any pending interrupt after flush is handled.
+ * Merged setBase() into init() as it wasn't required anywhere else.
+ * Changed init() to enforce _uidx is set by Serial to define the _base
+ address of the Uart in use.
+
1.1 - 20/11/2010
* Added this file
--- a/FLUSH.cpp Sun Nov 21 02:15:07 2010 +0000
+++ b/FLUSH.cpp Sun Nov 21 03:31:51 2010 +0000
@@ -28,9 +28,6 @@
void
MODSERIAL::flushBuffer(IrqType type)
{
- volatile char c __attribute__((unused));
- volatile uint32_t iir __attribute__((unused));
-
uint32_t ier = _IER;
switch(type) {
case TxIrq: _IER &= ~(1UL << 1); break;
@@ -40,9 +37,10 @@
buffer_out[type] = 0;
buffer_count[type] = 0;
buffer_overflow[type] = 0;
- _FCR = MODSERIAL_FIFO_RX_RESET | MODSERIAL_FIFO_TX_RESET;
- _FCR = MODSERIAL_FIFO_ENABLE;
- iir = _IIR;
+ switch(type) {
+ case TxIrq: _FCR = MODSERIAL_FIFO_TX_RESET; break;
+ case RxIrq: _FCR = MODSERIAL_FIFO_RX_RESET; break;
+ }
_IER = ier;
}
--- a/INIT.cpp Sun Nov 21 02:15:07 2010 +0000
+++ b/INIT.cpp Sun Nov 21 03:31:51 2010 +0000
@@ -30,7 +30,13 @@
{
disableIrq();
- setBase();
+ switch(_uidx) {
+ case 0: _base = LPC_UART0; break;
+ case 1: _base = LPC_UART1; break;
+ case 2: _base = LPC_UART2; break;
+ case 3: _base = LPC_UART3; break;
+ default : _base = NULL; break;
+ }
if (_base != NULL) {
buffer_size[RxIrq] = rxSize;
@@ -39,6 +45,7 @@
buffer_out[RxIrq] = 0;
buffer_count[RxIrq] = 0;
buffer_overflow[RxIrq] = 0;
+ dmaInUse[RxIrq] = -1;
Serial::attach(this, &MODSERIAL::isr_rx, Serial::RxIrq);
buffer_size[TxIrq] = txSize;
@@ -47,8 +54,12 @@
buffer_out[TxIrq] = 0;
buffer_count[TxIrq] = 0;
buffer_overflow[TxIrq] = 0;
+ dmaInUse[TxIrq] = -1;
Serial::attach(this, &MODSERIAL::isr_tx, Serial::TxIrq);
}
+ else {
+ error("MODSERIAL must have a defined UART to function.");
+ }
if (!txBufferSane()) {
error("Failed to allocate memory for TX buffer");
@@ -63,16 +74,4 @@
enableIrq();
}
-void
-MODSERIAL::setBase(void)
-{
- switch(_uidx) {
- case 0: _base = LPC_UART0; break;
- case 1: _base = LPC_UART1; break;
- case 2: _base = LPC_UART2; break;
- case 3: _base = LPC_UART3; break;
- default : _base = NULL; break;
- }
-}
-
}; // namespace AjK ends
--- a/ISR_RX.cpp Sun Nov 21 02:15:07 2010 +0000
+++ b/ISR_RX.cpp Sun Nov 21 03:31:51 2010 +0000
@@ -28,7 +28,9 @@
void
MODSERIAL::isr_rx(void)
{
- if (_base) {
+ if (! _base ) return;
+
+ if ( dmaInUse[RxIrq] == NotInUse ) {
while( MODSERIAL_RBR_HAS_DATA ) {
rxc = (char)(_RBR & 0xFF);
if ( MODSERIAL_RX_BUFFER_FULL ) {
--- a/ISR_TX.cpp Sun Nov 21 02:15:07 2010 +0000
+++ b/ISR_TX.cpp Sun Nov 21 03:31:51 2010 +0000
@@ -29,7 +29,9 @@
void
MODSERIAL::isr_tx(void)
{
- if (_base) {
+ if (! _base ) return;
+
+ if (dmaInUse[TxIrq] == NotInUse ) {
while (! MODSERIAL_TX_BUFFER_EMPTY && MODSERIAL_THR_HAS_SPACE ) {
_THR = txc = (uint8_t)(buffer[TxIrq][buffer_out[TxIrq]]);
buffer_count[TxIrq]--;
--- a/MODSERIAL.cpp Sun Nov 21 02:15:07 2010 +0000
+++ b/MODSERIAL.cpp Sun Nov 21 03:31:51 2010 +0000
@@ -71,6 +71,12 @@
return MODSERIAL_RX_BUFFER_EMPTY;
}
+bool
+MODSERIAL::txIsBusy(void)
+{
+ return (_LSR & (3UL << 5) == 0) ? true : false;
+}
+
void
MODSERIAL::disableIrq(void)
{
--- a/MODSERIAL.h Sun Nov 21 02:15:07 2010 +0000
+++ b/MODSERIAL.h Sun Nov 21 03:31:51 2010 +0000
@@ -134,6 +134,19 @@
, BufferOversize = -2 /*!< Oversized buffer. */
};
+ //! DMA channels.
+ enum dmaChannel {
+ NotInUse = -1 /*!< DMA not in use */
+ , Channel0 = 0 /*!< Channel 0 */
+ , Channel1 /*!< Channel 1 */
+ , Channel2 /*!< Channel 2 */
+ , Channel3 /*!< Channel 3 */
+ , Channel4 /*!< Channel 4 */
+ , Channel5 /*!< Channel 5 */
+ , Channel6 /*!< Channel 6 */
+ , Channel7 /*!< Channel 7 */
+ };
+
/**
* The MODSERIAL constructor is used to initialise the serial object.
*
@@ -549,7 +562,7 @@
* @ingroup API
* @return bool
*/
- bool txIsBusy(void) { return (_LSR & (3UL << 5) == 0) ? true : false; }
+ bool txIsBusy(void);
#if 0 // Inhereted from Serial/Stream, for documentation only
/**
@@ -650,6 +663,12 @@
volatile int buffer_overflow[2];
/**
+ * DMA channel in use.
+ * @ingroup INTERNALS
+ */
+ volatile int dmaInUse[2];
+
+ /**
* Callback system.
* @ingroup INTERNALS
*/
@@ -706,13 +725,7 @@
* Overloaded virtual function.
*/
virtual int _getc() { return __getc(true); }
-
- /**
- * Set's the Uart base pointer.
- * @ingroup INTERNALS
- */
- void setBase(void);
-
+
/**
* Function: init
* Initialize the MODSERIAL object
--- a/PUTC.cpp Sun Nov 21 02:15:07 2010 +0000
+++ b/PUTC.cpp Sun Nov 21 03:31:51 2010 +0000
@@ -29,24 +29,26 @@
MODSERIAL::__putc(int c, bool block) {
uint32_t lsr = (uint32_t)*((char *)_base + MODSERIAL_LSR);
- if (lsr & 0x20 && MODSERIAL_TX_BUFFER_EMPTY ) {
- _THR = (uint32_t)c;
- }
- else {
- if (buffer[TxIrq] != (char *)NULL) {
- if (block) while ( MODSERIAL_TX_BUFFER_FULL ) ; // Blocks!
- else if( MODSERIAL_TX_BUFFER_FULL ) {
- buffer_overflow[TxIrq] = c; // Oh dear, no room in buffer.
- _isr[TxOvIrq].call();
- return -1;
+ if ( dmaInUse[TxIrq] == NotInUse ) {
+ if (lsr & 0x20 && MODSERIAL_TX_BUFFER_EMPTY ) {
+ _THR = (uint32_t)c;
+ }
+ else {
+ if (buffer[TxIrq] != (char *)NULL) {
+ if (block) while ( MODSERIAL_TX_BUFFER_FULL ) ; // Blocks!
+ else if( MODSERIAL_TX_BUFFER_FULL ) {
+ buffer_overflow[TxIrq] = c; // Oh dear, no room in buffer.
+ _isr[TxOvIrq].call();
+ return -1;
+ }
+ buffer[TxIrq][buffer_in[TxIrq]] = c;
+ buffer_count[TxIrq]++;
+ buffer_in[TxIrq]++;
+ if (buffer_in[TxIrq] >= buffer_size[TxIrq]) {
+ buffer_in[TxIrq] = 0;
+ }
+ _IER |= 0x2;
}
- buffer[TxIrq][buffer_in[TxIrq]] = c;
- buffer_count[TxIrq]++;
- buffer_in[TxIrq]++;
- if (buffer_in[TxIrq] >= buffer_size[TxIrq]) {
- buffer_in[TxIrq] = 0;
- }
- _IER |= 0x2;
}
}
--- a/example.cpp Sun Nov 21 02:15:07 2010 +0000
+++ b/example.cpp Sun Nov 21 03:31:51 2010 +0000
@@ -54,7 +54,7 @@
// Ensure the baud rate for the PC "USB" serial is much
// higher than "uart" baud rate below.
- pc.baud(115200);
+ pc.baud(PC_BAUD);
// Use a deliberatly slow baud to fill up the TX buffer
uart.baud(1200);
