ssize_t apc220_write_str(const void *ptr, size_t len) { const char *c = (const char*) ptr; int exit; int abort = 0; for (int i = 0; i < len && !abort; i++) { exit = 0; while (!exit) { if( xSemaphoreTake( xSemaphoreTx, ( portTickType ) 10 ) == pdTRUE ) { exit = rb_putc(&tx_buf, *c); xSemaphoreGive( xSemaphoreTx ); } else { // Abort writing, it's locked by other task len = -1; abort = pdTRUE; exit = 1; } } if (*c == '\0') break; c++; } return len; }
void USART1_IRQHandler(void) { static signed portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; if ( USART_GetITStatus(USART1, USART_IT_RXNE) ) { if ( xSemaphoreRx != NULL ) { if (xQueueReceiveFromISR( xSemaphoreRx, NULL, NULL)) { // The first rx buffer is available xSemaphoreGiveFromISR( xSemaphoreRx, &xHigherPriorityTaskWoken ); rb_putc(&rx_buf1, USART1->DR); } else { // The first rx buffer is locked by the reader task // so we have to use the second buffer which is of course available rb_putc(&rx_buf2, USART1->DR); uart_stats.rx_buff1_busy++; } } uart_stats.rx_bytes++; } }
ssize_t uart_write_r(struct _reent *r, int fd, const void *ptr, size_t len) { const char *c = (const char*) ptr; for (int i = 0; i < len; i++) { while (!rb_putc(&tx_buf, *c)); c++; // Enable TX empty interrupt USART1->CR1 |= USART_CR1_TXEIE; } return len; }
void USART1_IRQHandler(void) { if (USART1->SR & USART_SR_RXNE) { if (!rb_putc(&rx_buf, USART1->DR)) uart_stats.rx_overrun++; else uart_stats.rx_bytes++; } if (USART1->SR & USART_SR_TXE) { char c; if (rb_getc(&tx_buf, &c)) { // send a queued byte // USART1->DR = c; } else { // nothing to send, disable interrupt // USART1->CR1 &= ~USART_CR1_TXEIE; } uart_stats.tx_bytes++; } }