/* Find out what interrupted and get or send data as appropriate */ void MB_USART_ISR(void) { /* Check if we were called because of RXNE. */ if (((USART_CR1(MB_USART) & USART_CR1_RXNEIE) != 0) && ((USART_SR(MB_USART) & USART_SR_RXNE) != 0)) { pxMBFrameCBByteReceived(); } /* Check if we were called because of TXE. */ if (((USART_CR1(MB_USART) & USART_CR1_TXEIE) != 0) && ((USART_SR(MB_USART) & USART_SR_TXE) != 0)) { pxMBFrameCBTransmitterEmpty(); /* Check if we need to disable transmitter*/ if(!txen) { USART_SR (MB_USART) &= ~USART_SR_TC; /* Clear TC flag*/ USART_CR1(MB_USART) |= USART_CR1_TCIE; /* Enable transfer complite interrupt*/ } } /* Disable transmitter on transfer comlite*/ if (((USART_CR1(MB_USART) & USART_CR1_TCIE) != 0) && ((USART_SR(MB_USART) & USART_SR_TC) != 0)) { USART_CR1(MB_USART) &= ~USART_CR1_TCIE;/* Disble transfer complite interrupt*/ USART_SR (MB_USART) &= ~USART_SR_TC; /* Clear TC flag*/ /* Disable transmitter*/ gpio_clear(MB_USART_TXEN_PORT, MB_USART_TXEN_PIN); } }
void usart1_isr(void) { unsigned char c; /* Check if we were called because of RXNE. */ if (((USART_CR1(USART1) & USART_CR1_RXNEIE) != 0) && ((USART_SR(USART1) & USART_SR_RXNE) != 0) && (!serial_rb_full(&srx))) { c = serial_recv(); serial_rb_write(&srx, c); } /* Check if we were called because of TXE. */ else if (((USART_CR1(USART1) & USART_CR1_TXEIE) != 0) && ((USART_SR(USART1) & USART_SR_TXE) != 0)) { if(!serial_rb_empty(&stx)) { serial_send(serial_rb_read(&stx)); } else { /* Disable the TXE interrupt, it's no longer needed. */ USART_CR1(USART1) &= ~USART_CR1_TXEIE; } } else { c = serial_recv(); } }
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 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; } }
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); } }
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); } } }
/** * 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(); } } }
void UART_IRQHandler(struct CB_UART* pctl) { /* Receive */ if ((USART_SR(pctl->iuart) & USART_SR_RXNE) != 0) // Receive reg loaded? { // Here, receive interrupt flag is on. *pctl->rxbuff_in = USART_DR(pctl->iuart);// Read and store char /* Advance pointers to line buffers and array of counts and reset when end reached */ pctl->rxbuff_in = rxbuff_adv(pctl, pctl->rxbuff_in); // Advance pointers common routine } /* Transmit */ if ( (USART_CR1(pctl->iuart) & USART_CR1_TXEIE) != 0) { // Here, yes. Transmit interrupts are enabled so check if a tx interrupt if ( (USART_SR(pctl->iuart) & USART_SR_TXE) != 0) // Transmit register empty? { // Here, yes. USART_DR(pctl->iuart) = *pctl->txbuff_out;// Send next char, step pointer /* Advance output pointer */ pctl->txbuff_out = txbuff_adv(pctl, pctl->txbuff_out); /* Was the last byte loaded the last to send? */ if (pctl->txbuff_out == pctl->txbuff_in) { // Here yes. USART_CR1(pctl->iuart) &= ~USART_CR1_TXEIE; // Disable Tx interrupt } } } return; }
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); } } }
/* * Common USART/UART transmit and receive interrupts are * collated to here. Each serial port simply redirects to here * while passing in its BASE address in peripheral space and the * channel # it has been assigned. The channel number mapping is * established at initialization time. */ void common_usart_isr(uint32_t usart, int channel) { if (USART_SR(usart) & USART_SR_RXNE) { recv_buf[channel][nxt_recv_ndx[channel]] = USART_DR(usart); nxt_recv_ndx[channel] = (nxt_recv_ndx[channel] + 1) % UART_BUF_SIZE; } if (USART_SR(usart) & USART_SR_TXE) { if (nxt_xmit_ndx[channel] == cur_xmit_ndx[channel]) { usart_disable_tx_interrupt(usart); // nothing to send } else { USART_DR(usart) = xmit_buf[channel][cur_xmit_ndx[channel]]; cur_xmit_ndx[channel] = (cur_xmit_ndx[channel] + 1) % UART_BUF_SIZE; } } }
/** Helper function that schedules a new transfer with the DMA controller if * needed. * \param s The USART DMA state structure. * */ static void dma_schedule(usart_tx_dma_state* s) { /* TODO: We shouldn't have to check for this now that we are called * atomically but leaving it in for now just in case. */ if (DMA_SCR(s->dma, s->stream) & DMA_SxCR_EN) screaming_death("DMA TX scheduled while DMA channel running"); DMA_SM0AR(s->dma, s->stream) = &(s->buff[s->rd]); /* Save the transfer length so we can increment the read index after the * transfer is finished. */ if (s->rd < s->wr) /* DMA up until write pointer. */ s->xfer_len = s->wr - s->rd; else /* DMA up until the end of the buffer. */ s->xfer_len = USART_TX_BUFFER_LEN - s->rd; /* Set the number of datas in the DMA controller. */ DMA_SNDTR(s->dma, s->stream) = s->xfer_len; /* Clear USART_TC flag */ USART_SR(s->usart) &= ~USART_SR_TC; /* Enable DMA stream to start transfer. */ DMA_SCR(s->dma, s->stream) |= DMA_SxCR_EN; }
/* For interrupt handling we add a new function which is called * when recieve interrupts happen. The name (usart1_isr) is created * by the irq.json file in libopencm3 calling this interrupt for * USART2 'usart2', adding the suffix '_isr', and then weakly binding * it to the 'do nothing' interrupt function in vec.c. * * By defining it in this file the linker will override that weak * binding and instead bind it here, but you have to get the name * right or it won't work. And you'll wonder where your interrupts * are going. */ void usart1_isr(void) { uint32_t reg; int i; do { reg = USART_SR(CONSOLE_UART); if (reg & USART_SR_RXNE) { recv_buf[recv_ndx_nxt] = USART_DR(CONSOLE_UART); #ifdef RESET_ON_CTRLC /* * This bit of code will jump to the ResetHandler if you * hit ^C */ if (recv_buf[recv_ndx_nxt] == '\003') { scb_reset_system(); return; /* never actually reached */ } #endif /* Check for "overrun" */ i = (recv_ndx_nxt + 1) % RECV_BUF_SIZE; if (i != recv_ndx_cur) { recv_ndx_nxt = i; } } /* can read back-to-back interrupts */ } while ((reg & USART_SR_RXNE) != 0); }
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); }
/* * uart_putc(char c) * * Write a character the uart (Blocking). This does what it says, * puts out a character to the serial port. If one is in the process * of being sent it waits until it finishes then puts this one out. */ void uart_putc(char c) { while (!(USART_SR(USART6) & USART_SR_TXE)) { __asm__("NOP"); } USART_DR(USART6) = (uint16_t)(c & 0xff); }
int uart7_cin(uint32_t whichUsart) { int c = -1; if (USART_SR(whichUsart) & USART_SR_RXNE) { c = usart_recv(whichUsart); } return c; }
/* * console_putc(char c) * * Send the character 'c' to the USART, wait for the USART * transmit buffer to be empty first. */ void console_putc(char c) { uint32_t reg; do { reg = USART_SR(CONSOLE_UART); } while ((reg & USART_SR_TXE) == 0); USART_DR(CONSOLE_UART) = (uint16_t) c & 0xff; }
void Stm32SerialIO<u32 irq>::Isr(void) { if (USART_SR(usart) & USART_SR_RXNE) { char c=usart_recv(usart); this->handler->NewChar(c); } }
bool send_byte(u8 byte) { if(USART_SR(USART) & USART_SR_TXE) { USART_DR(USART) = byte; return true; } return false; }
int cin(void) { int c = -1; if (USART_SR(usart) & USART_SR_RXNE) c = usart_recv(usart); return c; }
int uart_cin(void) { int c = -1; if (USART_SR(usart) & USART_SR_RXNE) { c = usart_recv(usart); } return c; }
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); } }
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)) { serial_rxint(); } /* Check if we were called because of TXE. */ if (((USART_CR1(USART2) & USART_CR1_TXEIE) != 0) && ((USART_SR(USART2) & USART_SR_TXE) != 0)) { serial_txint(); } }
bool usart_get_interrupt_source(u32 usart, u32 flag) { u32 flag_set = (USART_SR(usart) & flag); /* IDLE, RXNE, TC, TXE interrupts */ if ((flag >= USART_SR_IDLE) && (flag <= USART_SR_TXE)) return ((flag_set & USART_CR1(usart)) != 0); /* Overrun error */ else if (flag == USART_SR_ORE) return (flag_set && (USART_CR3(usart) & USART_CR3_CTSIE)); return (false); }
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; }
bool usart_get_interrupt_source(uint32_t usart, uint32_t flag) { uint32_t flag_set = (USART_SR(usart) & flag); /* IDLE, RXNE, TC, TXE interrupts */ if ((flag >= USART_SR_IDLE) && (flag <= USART_SR_TXE)) { return ((flag_set & USART_CR1(usart)) != 0); /* Overrun error */ } else if (flag == USART_SR_ORE) { return flag_set && (USART_CR3(usart) & USART_CR3_CTSIE); } return false; }
// common void UART_isr(uint32_t UART) { uint8_t bufidx = 0, data; UART_buff *curbuff; // Check if we were called because of RXNE if(USART_SR(UART) & USART_SR_RXNE) { // parce incoming byte data = usart_recv(UART); fill_uart_RXbuff(UART, data); } // Check if we were called because of TXE -> send next byte in buffer if((USART_CR1(UART) & USART_CR1_TXEIE) && (USART_SR(UART) & USART_SR_TXE)) { switch(UART) { case USART1: bufidx = 0; break; case USART2: bufidx = 1; break; default: // error - return return; } curbuff = &TX_buffer[bufidx]; bufidx = curbuff->start; // start of data in buffer if(bufidx != curbuff->end) { // there's data in buffer // Put data into the transmit register usart_send(UART, curbuff->buf[bufidx]); if(++(curbuff->start) == UART_BUF_DATA_SIZE) { // reload start curbuff->start = 0; } } else { // Disable the TXE interrupt, it's no longer needed USART_CR1(UART) &= ~USART_CR1_TXEIE; // empty indexes curbuff->start = 0; curbuff->end = 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++; } } }
int dbg_serial_write( unsigned char *d, unsigned short n ) { int res = 0; cm_disable_interrupts(); res = dbg_fifo_write( &usart_tx_buf, d, n ); if( res && !(USART_CR1(DBG_USART) & USART_CR1_TXEIE) ) { if( dbg_fifo_read_byte( &usart_tx_buf, &usart_data ) ) { while( !(USART_SR(DBG_USART) & USART_SR_TXE) );///пока буфер не пуст usart_send(DBG_USART, usart_data); usart_enable_tx_interrupt(DBG_USART); } } cm_enable_interrupts(); return res; }
// put byte into Tx buffer void fill_uart_buff(uint32_t UART, uint8_t byte) { UART_buff *curbuff; uint8_t bufidx = 0, endidx; if(!(USART_CR1(UART) & USART_CR1_UE)) return; // UART disabled USART_CR1(UART) &= ~USART_CR1_TXEIE; // disable TX interrupt while buffer filling while ((USART_SR(UART) & USART_SR_TXE) == 0); // wait until last byte send switch(UART) { case USART1: bufidx = 0; break; case USART2: bufidx = 1; break; default: // error - return return; } curbuff = &TX_buffer[bufidx]; bufidx = curbuff->start; // start of data in buffer endidx = curbuff->end; // end of data curbuff->buf[endidx++] = byte; // put byte into buffer // now check indexes if(endidx != bufidx && endidx != UART_BUF_DATA_SIZE) { // all OK - there's enough place for data (curbuff->end)++; // just increment index in buffer } else { // dangerous situation: possible overflow if(endidx == UART_BUF_DATA_SIZE) { // end of buffer if(bufidx != 0) { // no overflow curbuff->end = 0; goto end_of_fn; } } // overflow: purge all data bufidx = curbuff->start; // refresh data index for(endidx = bufidx; endidx < UART_BUF_DATA_SIZE; endidx++) // first data porion usart_send(UART, curbuff->buf[endidx]); for(endidx = 0; endidx < bufidx; endidx++) // rest of data usart_send(UART, curbuff->buf[endidx]); curbuff->start = 0; curbuff->end = 0; return; } end_of_fn: // enable interrupts to send data from buffer USART_CR1(UART) |= USART_CR1_TXEIE; }
static bool put_console_char(int8_t c) { int timeout_cnt = 100; /* allow 100msec for USART busy timeout*/ bool ret_stat = false; do { /* check Tx register ready transmissiion */ if(USART_SR(USART3_BASE) & USART_SR_TXE) { USART_DR(USART3_BASE) = c; ret_stat = true; break; } delay_ms(1); /* 1 ms sampling */ } while(--timeout_cnt); return(ret_stat); }