OSStatus BUartRecv( mico_uart_t uart, void* data, uint32_t size, uint32_t timeout ) { while (size != 0) { uint32_t transfer_size = MIN(uart_interfaces[uart].rx_buffer->size / 2, size); /* Check if ring buffer already contains the required amount of data. */ if ( transfer_size > (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0) ) { /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */ uart_interfaces[uart].rx_size = transfer_size; BuartIOctl(BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, uart_interfaces[uart].rx_size-1); BuartIOctl(UART_IOCTL_RXINT_SET, 1); #ifndef NO_MICO_RTOS if ( mico_rtos_get_semaphore( &uart_interfaces[uart].rx_complete, timeout) != kNoErr ) { //BuartIOctl(UART_IOCTL_RXINT_SET, 0); uart_interfaces[uart].rx_size = 0; return kTimeoutErr; } #else uart_interfaces[uart].rx_complete = false; int delay_start = mico_get_time_no_os(); while(uart_interfaces[uart].rx_complete == false){ if(mico_get_time_no_os() >= delay_start + timeout && timeout != MICO_NEVER_TIMEOUT){ uart_interfaces[uart].rx_size = 0; return kTimeoutErr; } } #endif /* Reset rx_size to prevent semaphore being set while nothing waits for the data */ uart_interfaces[uart].rx_size = 0; } size -= transfer_size; // Grab data from the buffer do { uint32_t bytes_available; bytes_available = (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0); bytes_available = MIN( bytes_available, transfer_size ); BuartRecv(data, bytes_available, 0); transfer_size -= bytes_available; data = ( (uint8_t*) data + bytes_available ); } while ( transfer_size != 0 ); } if ( size != 0 ) { return kGeneralErr; } else { return kNoErr; } }
static OSStatus BUartRecv( platform_uart_driver_t* driver, void* data, uint32_t size, uint32_t timeout ) { int next_trigger; uint32_t recved_data_len = (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0); uint32_t delay_start = 0; while (size != 0) { uint32_t transfer_size = MIN( BUART_RX_FIFO_SIZE / 2, size ); /* Check if ring buffer already contains the required amount of data. */ if ( transfer_size > recved_data_len ) { /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */ driver->rx_size = transfer_size; next_trigger = (driver->buart_fifo_head + driver->rx_size - 1)% BUART_RX_FIFO_SIZE; /* */ if( next_trigger < driver->buart_fifo_head && (driver->buart_fifo_head + recved_data_len) < BUART_RX_FIFO_SIZE ){ BuartIOctl( BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, BUART_RX_FIFO_SIZE - 1 ); BuartIOctl(UART_IOCTL_RXINT_CLR, 0); BuartIOctl(UART_IOCTL_RXINT_SET, 1); #ifndef NO_MICO_RTOS #if 0 if ( mico_rtos_get_semaphore( &driver->rx_complete, timeout) != kNoErr ) { driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } #else delay_start = mico_get_time(); while(1){ mico_rtos_get_semaphore( &driver->rx_complete, 50); if( (BUART_RX_FIFO_SIZE - driver->buart_fifo_head) <= (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0) ) break; if( mico_get_time() - delay_start > timeout ){ driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } } #endif #else driver->rx_complete = false; int delay_start = mico_get_time_no_os(); while(driver->rx_complete == false){ if(mico_get_time_no_os() >= delay_start + timeout && timeout != MICO_NEVER_TIMEOUT){ driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } } #endif mico_thread_msleep(20); } #ifndef NO_MICO_RTOS #if 1 recved_data_len = (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0); if ( transfer_size > recved_data_len ){ BuartIOctl(UART_IOCTL_RXINT_CLR, 0); BuartIOctl( BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, next_trigger ); BuartIOctl(UART_IOCTL_RXINT_SET, 1); if ( mico_rtos_get_semaphore( &driver->rx_complete, timeout) != kNoErr ) { driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } } else{ driver->rx_size = 0; } #else //platform_log( "Waiting...,head:%d expext:%d trigger:%d", driver->buart_fifo_head, driver->rx_size, next_trigger ); BuartIOctl(UART_IOCTL_RXINT_CLR, 0); BuartIOctl( BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, next_trigger ); BuartIOctl(UART_IOCTL_RXINT_SET, 1); delay_start = mico_get_time(); while(1){ mico_rtos_get_semaphore( &driver->rx_complete, 50); if( driver->rx_size <= (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0) ) break; if( mico_get_time() - delay_start > timeout ){ driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } } #endif #else BuartIOctl(UART_IOCTL_RXINT_CLR, 0); BuartIOctl( BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, next_trigger ); BuartIOctl(UART_IOCTL_RXINT_SET, 1); driver->rx_complete = false; delay_start = mico_get_time_no_os(); while(driver->rx_complete == false){ if(mico_get_time_no_os() >= delay_start + timeout && timeout != MICO_NEVER_TIMEOUT){ driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } } #endif /* Reset rx_size to prevent semaphore being set while nothing waits for the data */ driver->rx_size = 0; } size -= transfer_size; // Grab data from the buffer do { uint32_t bytes_available; bytes_available = (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0); bytes_available = MIN( bytes_available, transfer_size ); BuartRecv(data, bytes_available, 0); driver->buart_fifo_head = (driver->buart_fifo_head + bytes_available)% BUART_RX_FIFO_SIZE; transfer_size -= bytes_available; } while ( transfer_size != 0 ); } if ( size != 0 ) { return kGeneralErr; } else { return kNoErr; } }