Added optional interrupt-based transmission, based on the ringbuf library
This commit is contained in:
parent
d813d343c5
commit
6ab7ac0598
1 changed files with 57 additions and 4 deletions
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* @(#)$Id: uart1.c,v 1.9 2009/02/24 21:31:10 adamdunkels Exp $
|
* @(#)$Id: uart1.c,v 1.10 2009/03/01 20:40:30 adamdunkels Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -42,13 +42,27 @@
|
||||||
#include "dev/leds.h"
|
#include "dev/leds.h"
|
||||||
#include "dev/watchdog.h"
|
#include "dev/watchdog.h"
|
||||||
|
|
||||||
|
#include "lib/ringbuf.h"
|
||||||
|
|
||||||
static int (*uart1_input_handler)(unsigned char c);
|
static int (*uart1_input_handler)(unsigned char c);
|
||||||
static uint8_t rx_in_progress;
|
static uint8_t rx_in_progress;
|
||||||
|
|
||||||
|
static volatile uint8_t transmitting;
|
||||||
|
|
||||||
|
#define TX_WITH_INTERRUPT 1
|
||||||
|
|
||||||
|
#if TX_WITH_INTERRUPT
|
||||||
|
#define TXBUFSIZE 64
|
||||||
|
|
||||||
|
static struct ringbuf txbuf;
|
||||||
|
static uint8_t txbuf_data[TXBUFSIZE];
|
||||||
|
#endif /* TX_WITH_INTERRUPT */
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uint8_t
|
uint8_t
|
||||||
uart1_active(void)
|
uart1_active(void)
|
||||||
{
|
{
|
||||||
return ((~ UTCTL1) & TXEPT) | rx_in_progress;
|
return ((~ UTCTL1) & TXEPT) | rx_in_progress | transmitting;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -60,12 +74,30 @@ uart1_set_input(int (*input)(unsigned char c))
|
||||||
void
|
void
|
||||||
uart1_writeb(unsigned char c)
|
uart1_writeb(unsigned char c)
|
||||||
{
|
{
|
||||||
|
#if TX_WITH_INTERRUPT
|
||||||
|
|
||||||
|
/* Put the outgoing byte on the transmission buffer. If the buffer
|
||||||
|
is full, we just keep on trying to put the byte into the buffer
|
||||||
|
until it is possible to put it there. */
|
||||||
|
while(ringbuf_put(&txbuf, c) == 0) {
|
||||||
|
watchdog_periodic();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If there is no transmission going, we need to start it by putting
|
||||||
|
the first byte into the UART. */
|
||||||
|
if(transmitting == 0) {
|
||||||
|
transmitting = 1;
|
||||||
|
TXBUF1 = ringbuf_get(&txbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* TX_WITH_INTERRUPT */
|
||||||
watchdog_periodic();
|
watchdog_periodic();
|
||||||
/* Loop until the transmission buffer is available. */
|
/* Loop until the transmission buffer is available. */
|
||||||
while((IFG2 & UTXIFG1) == 0);
|
while((IFG2 & UTXIFG1) == 0);
|
||||||
|
|
||||||
/* Transmit the data. */
|
/* Transmit the data. */
|
||||||
TXBUF1 = c;
|
TXBUF1 = c;
|
||||||
|
#endif /* TX_WITH_INTERRUPT */
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if ! WITH_UIP /* If WITH_UIP is defined, putchar() is defined by the SLIP driver */
|
#if ! WITH_UIP /* If WITH_UIP is defined, putchar() is defined by the SLIP driver */
|
||||||
|
@ -127,12 +159,17 @@ uart1_init(unsigned long ubr)
|
||||||
|
|
||||||
rx_in_progress = 0;
|
rx_in_progress = 0;
|
||||||
|
|
||||||
IE2 |= URXIE1; /* Enable USART1 RX interrupt */
|
transmitting = 0;
|
||||||
|
|
||||||
|
IE2 |= URXIE1; /* Enable USART1 RX interrupt */
|
||||||
|
#if TX_WITH_INTERRUPT
|
||||||
|
IE2 |= UTXIE1; /* Enable USART1 RX interrupt */
|
||||||
|
ringbuf_init(&txbuf, txbuf_data, sizeof(txbuf_data));
|
||||||
|
#endif /* TX_WITH_INTERRUPT */
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
interrupt(UART1RX_VECTOR)
|
interrupt(UART1RX_VECTOR)
|
||||||
uart1_interrupt(void)
|
uart1_rx_interrupt(void)
|
||||||
{
|
{
|
||||||
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||||
|
|
||||||
|
@ -159,3 +196,19 @@ uart1_interrupt(void)
|
||||||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#if TX_WITH_INTERRUPT
|
||||||
|
interrupt(UART1TX_VECTOR)
|
||||||
|
uart1_tx_interrupt(void)
|
||||||
|
{
|
||||||
|
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||||
|
|
||||||
|
if(ringbuf_elements(&txbuf) == 0) {
|
||||||
|
transmitting = 0;
|
||||||
|
} else {
|
||||||
|
TXBUF1 = ringbuf_get(&txbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||||
|
}
|
||||||
|
#endif /* TX_WITH_INTERRUPT */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
Loading…
Reference in a new issue