示例#1
0
static int command(char *command, size_t length)
{
    size_t i;

    calculate_crc_and_ack(command, length);

    for (i = 0; i < length; i++)
        usart_send_blocking(USART2, command[i]);

    timer_set_counter(TIM5, 0);
    timer_clear_flag(TIM5, TIM_SR_UIF);
    timer_enable_counter(TIM5);

    for (i = 0; i < sizeof(expect_ack); )
    {
        while (!timer_get_flag(TIM5, TIM_SR_UIF) &&
               !usart_get_flag(USART2, USART_SR_RXNE));

        if (timer_get_flag(TIM5, TIM_SR_UIF))
            break;

        if (expect_ack[i] != usart_recv(USART2))
            break;
    }

    timer_disable_counter(TIM5);

    return (i == sizeof(expect_ack));
}
示例#2
0
/*
 * Read a character from the UART RX and stuff it in a software FIFO.
 * Allowed to read from FIFO out pointer, but not write to it.
 * Allowed to write to FIFO in pointer.
 */
void USBUSART_ISR(void)
{
	char c = usart_recv(USBUSART);

	/* Turn on LED */
	gpio_set(LED_PORT_UART, LED_UART);

	/* If the next increment of rx_in would put it at the same point
	* as rx_out, the FIFO is considered full.
	*/
	if (((buf_rx_in + 1) % FIFO_SIZE) != buf_rx_out)
	{
		/* insert into FIFO */
		buf_rx[buf_rx_in++] = c;

		/* wrap out pointer */
		if (buf_rx_in >= FIFO_SIZE)
		{
			buf_rx_in = 0;
		}

		/* enable deferred processing if we put data in the FIFO */
		timer_enable_irq(USBUSART_TIM, TIM_DIER_UIE);
	}
}
示例#3
0
void serial_rxint(void)
{
  uint8_t data = usart_recv(USART2);;
  uint32_t next_head;

  // Pick off realtime command characters directly from the serial stream. These characters are
  // not passed into the buffer, but these set system state flag bits for realtime execution.
  switch (data) {
    case CMD_STATUS_REPORT: bit_true_atomic(sys.rt_exec_state, EXEC_STATUS_REPORT); break; // Set as true
    case CMD_CYCLE_START:   bit_true_atomic(sys.rt_exec_state, EXEC_CYCLE_START); break; // Set as true
    case CMD_FEED_HOLD:     bit_true_atomic(sys.rt_exec_state, EXEC_FEED_HOLD); break; // Set as true
    case CMD_SAFETY_DOOR:   bit_true_atomic(sys.rt_exec_state, EXEC_SAFETY_DOOR); break; // Set as true
    case CMD_RESET:         mc_reset(); break; // Call motion control reset routine.
    default: // Write character to buffer
      next_head = serial_rx_buffer_head + 1;
      if (next_head == RX_BUFFER_SIZE) { next_head = 0; }

      // Write data to buffer unless it is full.
      if (next_head != serial_rx_buffer_tail) {
        serial_rx_buffer[serial_rx_buffer_head] = data;
        serial_rx_buffer_head = next_head;

        #ifdef ENABLE_XONXOFF
          if ((serial_get_rx_buffer_count() >= RX_BUFFER_FULL) && flow_ctrl == XON_SENT) {
            flow_ctrl = SEND_XOFF;
            usart_enable_tx_interrupt(USART2);
          }
        #endif

      }
      //TODO: else alarm on overflow?
  }
}
void usart1_isr(void)
{
	static uint8_t data = 'A';

	/* Check if we were called because of RXNE. */
	if (((USART_CR1(USART1) & USART_CR1_RXNEIE) != 0) &&
		((USART_SR(USART1) & USART_SR_RXNE) != 0)) {
		/* Indicate that we got data. */
		gpio_toggle(GPIOA, GPIO6);

		/* Retrieve the data from the peripheral. */
		data = usart_recv(USART1);

		/* Enable transmit interrupt so it sends back the data. */
		USART_CR1(USART1) |= USART_CR1_TXEIE;
	}

	/* Check if we were called because of TXE. */
	if (((USART_CR1(USART1) & USART_CR1_TXEIE) != 0) &&
		((USART_SR(USART1) & USART_SR_TXE) != 0)) {
		/* Indicate that we are sending out data. */
		gpio_toggle(GPIOA, GPIO7);

		/* Put data into the transmit register. */
		usart_send(USART1, data);

		/* Disable the TXE interrupt as we don't need it anymore. */
		USART_CR1(USART1) &= ~USART_CR1_TXEIE;
	}
}
示例#5
0
void usart1_isr(void)
{
	u8 ch;

	//if Receive interrupt
	if (((USART_CR1(USART1) & USART_CR1_RXNEIE) != 0) &&
			((USART_SR(USART1) & USART_SR_RXNE) != 0))
	{
		ch=usart_recv(USART1);
		buffer_put(&u1rx, ch);
	}

	if (((USART_CR1(USART1) & USART_CR1_TXEIE) != 0) &&
			((USART_SR(USART1) & USART_SR_TXE) != 0))
	{
		if (buffer_get(&u1tx, &ch) == SUCCESS)
		{
			//if char read from buffer
			usart_send(USART1, ch);
		}
		else	//if buffer empty
		{

			//disable Transmit Data Register empty interrupt
			usart_disable_tx_interrupt(USART1);
		}
	}
}
void usart2_isr(void)
{
	/* Check if we were called because of RXNE. */
	if (((USART_CR1(USART2) & USART_CR1_RXNEIE) != 0) &&
	    ((USART_SR(USART2) & USART_SR_RXNE) != 0)) {

		/* Indicate that we got data. */
		gpio_toggle(GPIOA, GPIO8);

		/* Retrieve the data from the peripheral. */
		ring_write_ch(&output_ring, usart_recv(USART2));

		/* Enable transmit interrupt so it sends back the data. */
		USART_CR1(USART2) |= USART_CR1_TXEIE;
	}

	/* Check if we were called because of TXE. */
	if (((USART_CR1(USART2) & USART_CR1_TXEIE) != 0) &&
	    ((USART_SR(USART2) & USART_SR_TXE) != 0)) {

		int32_t data;

		data = ring_read_ch(&output_ring, NULL);

		if (data == -1) {
			/* Disable the TXE interrupt, it's no longer needed. */
			USART_CR1(USART2) &= ~USART_CR1_TXEIE;
		} else {
			/* Put data into the transmit register. */
			usart_send(USART2, data);
		}
	}
}
示例#7
0
文件: main.c 项目: albedium/homeauto
void interrupt isr()
{
    while (RCIF) {
        usart_recv();
    }
    buttons_isr();
}
示例#8
0
int main(void)
{
	// Init GPIO: all leds on
	DDRA  = 0xFF;
	PORTA = 0xFF;

	// init USART (9600 baud, 8N1)
	usart_init();
	
	// make sure the USART works
	// (and PC can check that it has the right test)
	usart_send_str("async-n-semaphore test\r\n");

	// wait for the PC
	while (usart_recv() != 's')
		usart_send('?');

	// enable USART receive interrupts
	UCSRxB |= (1<<RXCIE0);

	// Init Os
	StartOS();

	//NOTE: Since OS is used, program will never get here!
    while(1);
}
示例#9
0
void usart2_isr(void)
{
	static u8 data = 'A';

	/* Check if we were called because of RXNE. */
	if (((USART_CR1(USART2) & USART_CR1_RXNEIE) != 0) &&
	    ((USART_SR(USART2) & USART_SR_RXNE) != 0)) {

		/* Indicate that we got data. */
		gpio_toggle(GPIOD, GPIO12);

		/* Retrieve the data from the peripheral. */
		data = usart_recv(USART2);

		/* Enable transmit interrupt so it sends back the data. */
		usart_enable_tx_interrupt(USART2);
	}

	/* Check if we were called because of TXE. */
	if (((USART_CR1(USART2) & USART_CR1_TXEIE) != 0) &&
	    ((USART_SR(USART2) & USART_SR_TXE) != 0)) {

		/* Put data into the transmit register. */
		usart_send(USART2, data);

		/* Disable the TXE interrupt as we don't need it anymore. */
		usart_disable_tx_interrupt(USART2);
	}
}
示例#10
0
文件: usart.c 项目: devnow/open-bldc
/**
 * USART interrupt handler.
 */
void usart1_isr(void)
{

	//TOGGLE(GREEN);
	/* input (RX) handler */
	if ((USART_SR(USART1) & USART_SR_RXNE) != 0) {
		data_buf = usart_recv(USART1);

		if (gpc_handle_byte((u8)data_buf) != 0) {
			//LED_GREEN_TOGGLE();
		} else {
			//LED_RED_ON();
		}
	}

	/* output (TX) handler */
	if ((USART_SR(USART1) & USART_SR_TXE) != 0) {
		if ((data_buf = gpc_pickup_byte()) >= 0) {
			usart_send(USART1, (uint16_t)data_buf);
			//LED_GREEN_TOGGLE();
		} else {
			usart_disable_send();
		}
	}
}
示例#11
0
文件: STM32_USART.c 项目: lireric/ssn
void usart3_isr(void)
{

	long xHigherPriorityTaskWoken = pdFALSE;
	char cChar;

	if (usart_get_flag(USART3, USART_SR_TXE) == true) {
		/* The interrupt was caused by the THR becoming empty.  Are there any
		 more characters to transmit? */
		if (xQueueReceiveFromISR(xCharsForTx[2], &cChar,
				&xHigherPriorityTaskWoken)) {
			gpio_set(GPIO_BANK_USART3_RTS, GPIO_USART3_RTS); // set RTS
			/* A character was retrieved from the buffer so can be sent to the THR now. */
			usart_send(USART3, (uint8_t) cChar);
		} else {
//			gpio_clear(GPIO_BANK_USART3_RTS, GPIO_USART3_RTS); // clear RTS
		}
	}

	if (usart_get_flag(USART3, USART_SR_RXNE) == true) {
		cChar = (char) usart_recv(USART3);
		xQueueSendFromISR(xRxedChars[2], &cChar, &xHigherPriorityTaskWoken);
	}

// ----- transmission complete:
	if (usart_get_flag(USART3, USART_SR_TC) == true) {
		gpio_clear(GPIO_BANK_USART3_RTS, GPIO_USART3_RTS); // clear RTS
		USART_SR(USART3) &= ~USART_SR_TC;	// reset flag TC
		usart_disable_tx_interrupt(USART3);
	}

	portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);

}
示例#12
0
void usart1_isr(void)
{
  if (usart_get_flag(USART1, USART_SR_RXNE)) {
    char c = usart_recv(USART1);
    if (c == '\n') {
      if (rx_head > 0) {
        rx_buf[rx_head] = 0;
        usart_on_line_recv(rx_buf, rx_head);
      }
      rx_head = 0;
    } else {
      rx_buf[rx_head] = c;
      rx_head = (rx_head + 1) % sizeof(rx_buf);
    }
  }

  if (usart_get_flag(USART1, USART_SR_TXE)) {
    if (waiting_tx_bytes() > 0) {
      usart_send(USART1, tx_buf[tx_tail]);
      tx_tail = (tx_tail + 1) % sizeof(tx_buf);
    } else {
      usart_disable_tx_interrupt(USART1);
    }
  }
}
示例#13
0
void DBG_USART_ISR(void)
{
    /* Check if we were called because of RXNE. */
    if (((USART_CR1(DBG_USART) & USART_CR1_RXNEIE) != 0) && ((USART_SR(DBG_USART) & USART_SR_RXNE) != 0))
    {
        usart_data = usart_recv(DBG_USART);
        if( !dbg_fifo_write_byte( &usart_rx_buf, usart_data ) )
        {
            usart_disable_rx_interrupt(DBG_USART);
        }
    }
    /* Check if we were called because of TXE. */
    if (((USART_CR1(DBG_USART) & USART_CR1_TXEIE) != 0) && ((USART_SR(DBG_USART) & USART_SR_TXE) != 0))
    {
        /* Put data into the transmit register. */
        if( dbg_fifo_read_byte( &usart_tx_buf, &usart_data ) )
        {
            usart_send(DBG_USART, usart_data);
        }
        else
        {
            /* Disable the TXE interrupt as we don't need it anymore. */
            usart_disable_tx_interrupt(DBG_USART);
        }
    }
}
示例#14
0
int uart7_cin(uint32_t whichUsart)
{
	int c = -1;
	if (USART_SR(whichUsart) & USART_SR_RXNE) {
	c = usart_recv(whichUsart);
	}
	return c;
}
示例#15
0
static inline void usart_isr(struct uart_periph* p) {

  if (((USART_CR1((u32)p->reg_addr) & USART_CR1_TXEIE) != 0) &&
      ((USART_SR((u32)p->reg_addr) & USART_SR_TXE) != 0)) {
    // check if more data to send
    if (p->tx_insert_idx != p->tx_extract_idx) {
      usart_send((u32)p->reg_addr,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
      USART_CR1((u32)p->reg_addr) &= ~USART_CR1_TXEIE; // Disable TX interrupt
    }
  }

  if (((USART_CR1((u32)p->reg_addr) & USART_CR1_RXNEIE) != 0) &&
      ((USART_SR((u32)p->reg_addr) & USART_SR_RXNE) != 0) &&
      ((USART_SR((u32)p->reg_addr) & USART_SR_ORE) == 0) &&
      ((USART_SR((u32)p->reg_addr) & USART_SR_NE) == 0) &&
      ((USART_SR((u32)p->reg_addr) & USART_SR_FE) == 0)) {
    uint16_t temp = (p->rx_insert_idx + 1) % UART_RX_BUFFER_SIZE;;
    p->rx_buf[p->rx_insert_idx] = usart_recv((u32)p->reg_addr);
    // check for more room in queue
    if (temp != p->rx_extract_idx)
      p->rx_insert_idx = temp; // update insert index
  }
  else {
    /* ORE, NE or FE error - read USART_DR reg and log the error */
    if (((USART_CR1((u32)p->reg_addr) & USART_CR1_RXNEIE) != 0) &&
        ((USART_SR((u32)p->reg_addr) & USART_SR_ORE) != 0)) {
      usart_recv((u32)p->reg_addr);
      p->ore++;
    }
    if (((USART_CR1((u32)p->reg_addr) & USART_CR1_RXNEIE) != 0) &&
        ((USART_SR((u32)p->reg_addr) & USART_SR_NE) != 0)) {
      usart_recv((u32)p->reg_addr);
      p->ne_err++;
    }
    if (((USART_CR1((u32)p->reg_addr) & USART_CR1_RXNEIE) != 0) &&
        ((USART_SR((u32)p->reg_addr) & USART_SR_FE) != 0)) {
      usart_recv((u32)p->reg_addr);
      p->fe_err++;
    }
  }
}
void Stm32SerialIO<u32 irq>::Isr(void)
{
   if (USART_SR(usart) & USART_SR_RXNE)
   {
      char c=usart_recv(usart);
      this->handler->NewChar(c);
   }
}
示例#17
0
文件: usart.c 项目: 3yc/PX4Bootloader
int
cin(void)
{
	int c = -1;

	if (USART_SR(usart) & USART_SR_RXNE)
		c = usart_recv(usart);
	return c;
}
示例#18
0
/* ----------------------- Get character ----------------------------------*/
BOOL
xMBPortSerialGetByte(CHAR * pucByte)
{
    /* Return the byte in the UARTs receive buffer. This function is called
     * by the protocol stack after pxMBFrameCBByteReceived( ) has been called.
     */
    *pucByte = (CHAR)usart_recv(MB_USART);
    return TRUE;
}
示例#19
0
static int silence_nmea()
{
    int attempt;
    size_t i;

    /* Configure the GPS */
    for (attempt = 0; attempt < 4; attempt++)
    {
        calculate_crc_and_ack(set_port, sizeof(silence_nmea));

        for (i = 0; i < sizeof(set_port); i++)
            usart_send_blocking(USART2, set_port[i]);

        timer_clear_flag(TIM5, TIM_SR_UIF);
        timer_set_counter(TIM5, 0);
        timer_enable_counter(TIM5);

        for (i = 0; i < sizeof(expect_ack); )
        {
            while (!timer_get_flag(TIM5, TIM_SR_UIF) &&
                   !usart_get_flag(USART2, USART_SR_RXNE));

            if (timer_get_flag(TIM5, TIM_SR_UIF))
                break;

            if (expect_ack[i] == usart_recv(USART2))
                i++;
            else
                i = 0;
        }

        timer_disable_counter(TIM5);

        if (i < sizeof(expect_ack))
            continue;
        else
            break;
    }

    while (usart_get_flag(USART2, USART_SR_RXNE))
        usart_recv(USART2);

    return attempt < 4;
}
示例#20
0
int uart_cin(void)
{
	int c = -1;

	if (USART_SR(usart) & USART_SR_RXNE) {
		c = usart_recv(usart);
	}

	return c;
}
示例#21
0
void usart1_isr() {
  if (usart_rx_end) {
    /* Already have unprocessed line in buffer */
    (void)usart_recv(USART1);
    return;
  }

  *usart_rx_dest = usart_recv(USART1);
  if (*usart_rx_dest == '\r') {
    *(usart_rx_dest + 1) = '\0';
    usart_rx_end = 1;
  }

  usart_rx_dest++;
  if (!usart_rx_end && 
      usart_rx_dest == config.console.rxbuffer + CONSOLE_BUFFER_SIZE - 1) {
    /* Buffer full */
    usart_rx_reset();
    return;
  }
}
示例#22
0
void usart_interrupt(void)
{
	if (usart_get_interrupt_source(usart, USART_SR_RXNE)) {
		uint8_t data = usart_recv(usart);
		usart_fifo_in_push(data);
		if ( data != 3 && data != '\r' && data != '\n') {
			usart_fifo_push(data);
		} else {
			LOG_PRINTF("\n>>");
		}
	}
}
示例#23
0
void BT_ISR(void)
{
    if (((USART_CR1(BTUART) & USART_CR1_RXNEIE) != 0) &&
        ((USART_ISR(BTUART) & USART_ISR_RXNE) != 0))
    {
        /* Retrieve the data from the peripheral. */
        *ptr = usart_recv(BTUART);
        if ((ptr - bt_buf) <  (int)sizeof(bt_buf) -1) {
            ptr++;
        }
        //printf("%c", *ptr);
    }
}
示例#24
0
文件: bsp.c 项目: mour/ratfist-stm32
/**
 * Interrupt handler for the USART1 peripheral.
 *
 * If the interrupt was caused by a received character, the handler adds the
 * chararacter to the rx_buffer. If the interrupt was caused by the peripheral
 * being ready to send a character, the handler takes one from the tx_buffer,
 * and writes it to the peripheral. In case the interrupt was caused by a USART
 * peripheral buffer overrun (typically happens during debugging), the handler
 * clears that interrupt flag.
 */
void usart1_isr(void)
{
	if (usart_get_flag(USART1, USART_ISR_RXNE)) {
		char ch = (char) usart_recv(USART1);
		os_char_buffer_write_ch(&bsp_rx_buffer, ch);

	} else if (usart_get_flag(USART1, USART_ISR_TXE)) {
		char ch = '\0';
		if (os_char_buffer_read_ch(&bsp_tx_buffer, &ch)) {
			usart_send(USART1, (uint8_t) ch);
		} else {
			usart_disable_tx_interrupt(USART1);
		}

	} else if (usart_get_flag(USART1, USART_ISR_ORE)) {
		USART_ICR(USART1) |= USART_ICR_ORECF;
	}
}
示例#25
0
void interrupt isr()
{
    while (RCIF) {
        usart_recv();
    }
    if (TMR1IF) {
        // Usually this event happens 128 times per second
        // (perios is about 7.8ms)
        TMR1IF = 0;
        unsigned char ticks = TMR1H;
        TMR1H = 0xff;
        if (ticks < 0xff)
            ticks++;
        // If some of ticks were missed, they are
        // counted in ticks variable
        usart_128_timer(ticks);
    }
}
示例#26
0
文件: commslib.c 项目: ksarkies/SMPS
void usart2_isr(void)
{
	static uint16_t data;

	/* Check if we were called because of RXNE. */
	if (usart_get_flag(USART2,USART_SR_RXNE))
	{
		/* If buffer full we'll just drop it */
		buffer_put(receiveBuffer, (uint8_t) usart_recv(USART2));
	}
	/* Check if we were called because of TXE. */
	if (usart_get_flag(USART2,USART_SR_TXE))
	{
		/* If buffer empty, disable the tx interrupt */
		data = buffer_get(sendBuffer);
		if ((data & 0xFF00) > 0) usart_disable_tx_interrupt(USART2);
		else usart_send(USART2, (data & 0xFF));
	}
}
示例#27
0
void Serial_stm32::irq_handler(void)
{
    uint8_t data = 0;

    // Check if we were called because of RXNE
    if (((USART_CR1(config_.device) & USART_CR1_RXNEIE) != 0) &&
            ((USART_SR(config_.device)  & USART_SR_RXNE)    != 0))
    {

        // Retrieve the data from the peripheral
        data = usart_recv(config_.device);
        rx_buffer_.put_lossy(data);

        // Enable transmit interrupt so it sends back the data
        usart_enable_tx_interrupt(config_.device);
    }

    // Check if we were called because of TXE
    if (((USART_CR1(config_.device) & USART_CR1_TXEIE) != 0) &&
            ((USART_SR(config_.device)  & USART_SR_TXE)    != 0))
    {
        if (tx_buffer_.readable() > 0)
        {
            // Get data from output buffer
            tx_buffer_.get(data);

            // Put data into the transmit register
            usart_send(config_.device, data);
        }
        else
        {
            // Disable the TXE interrupt as we don't need it anymore
            usart_disable_tx_interrupt(config_.device);
        }
    }

    // Call callback function if attached
    if (irq_callback != 0)
    {
        irq_callback(this);
    }
}
示例#28
0
void usart1_isr(void)
{
	static UNS16 data;

/* Check if we were called because of RXNE. */
	if (usart_get_flag(USART1,USART_SR_RXNE))
	{
/* Put to temporary message buffer */
		data = (UNS8) usart_recv(USART1);
		message_temp[msg_recv_status] = (UNS8) data;
		msg_recv_status++;
/* At this point we should check for integrity of the message, but there is no
way to recover if the message length sent is wrong. So we'll do what we can and
hope we can catch up eventually. */
		if ((msg_recv_status > 3) && (message_temp[3] > 8))
		{
/* Bad message length - abort and restart a new message */
			msg_recv_status = 0;
		}
/* Check if we are finished (message length is in element 3) */
		else if (msg_recv_status == 4 + message_temp[3])
		{
			msg_recv_status = 0;
			msg_received++;			/* Signal another message arrived */
			UNS8 i;
/* Dump to buffer; if full we'll just have to drop it */
			for (i=0; i < 4 + message_temp[3]; i++)
				buffer_put(receive_buffer,message_temp[i]);
		}
	}
/* Check if we were called because of TXE. */
	else if (usart_get_flag(USART1,USART_SR_TXE))
	{
		data = buffer_get(send_buffer);
/* If buffer empty, disable the tx interrupt */
		if ((data & 0xFF00) > 0) usart_disable_tx_interrupt(USART1);
		else
        {
                usart_send(USART1, (data & 0xFF));
        }
	}
}
示例#29
0
void usart1_isr(void)
{
	char c;
	if (usart_get_flag(USART1, USART_SR_TXE)) {
		if (!queue_is_empty(&uart_tx_buf)) {
			queue_dequeue(&uart_tx_buf, &c);
			usart_send(USART1, (uint16_t)c);
		} else {
			usart_disable_tx_interrupt(USART1);
		}
	}


	if (usart_get_flag(USART1, USART_SR_RXNE)) {
		if (!queue_is_full(&uart_rx_buf)) {
			c = usart_recv(USART1);
			queue_enqueue(&uart_rx_buf, &c);
		}
	}
}
示例#30
0
inline uint8_t
usart_respond_isr(int usart) {
  static uint8_t data = 'A';
  /* Check if we were called because of RXNE. */
  if (((USART_CR1(usart) & USART_CR1_RXNEIE) != 0) &&
      ((USART_SR(usart) & USART_SR_RXNE) != 0)) {
    /* Retrieve the data from the peripheral. */
    data = usart_recv(usart);
    /* Enable transmit interrupt so it sends back the data. */
    USART_CR1(usart) |= USART_CR1_TXEIE;
  }
  /* Check if we were called because of TXE. */
  if (((USART_CR1(usart) & USART_CR1_TXEIE) != 0) &&
      ((USART_SR(usart) & USART_SR_TXE) != 0)) {
    /* Put data into the transmit register. */
    usart_send(usart, data);
    /* Disable the TXE interrupt as we don't need it anymore. */
    USART_CR1(usart) &= ~USART_CR1_TXEIE;
  }
  return data;
}